Documentation Index Fetch the complete documentation index at: https://mintlify.com/LuisCastilloCruz/VIGIA/llms.txt
Use this file to discover all available pages before exploring further.
Overview
VIGIA provides direct API access to multiple global regulatory data sources, enabling on-demand queries without scraping delays. These endpoints supplement scheduled surveillance by providing real-time access to regulatory databases.
Available Sources
FDA US FDA medical device recalls and safety alerts
EMA European Medicines Agency safety updates
DIGEMID Peru regulatory authority alerts and product registry
VigiAccess WHO global adverse drug reaction database
Regulators API
Query multiple regulatory agencies for product information.
Base Path: /api/v1/regulators
Implementation: backend/app/routers/regulators.py
Search All Agencies
Search across all configured regulatory agencies simultaneously.
GET /api/v1/regulators/search?q={query}&max_items={limit}
Parameters:
Parameter Type Required Description qstring Yes Search query (drug name, active ingredient) max_itemsinteger No Maximum results per agency (default: 50)
Response:
[
{
"pais" : "United States" ,
"agencia" : "FDA" ,
"nombre_medicamento" : "Acetaminophen Tablets" ,
"sustancia_activa" : "Acetaminophen" ,
"forma_farmaceutica" : "Tablet" ,
"concentracion" : "500mg" ,
"titular" : "Generic Pharma Inc." ,
"estado" : "Autorizado" ,
"numero_registro" : "NDA021234" ,
"enlace" : "https://www.accessdata.fda.gov/..."
},
{
"pais" : "España" ,
"agencia" : "AEMPS" ,
"nombre_medicamento" : "Paracetamol 500mg comprimidos" ,
"sustancia_activa" : "Paracetamol" ,
"forma_farmaceutica" : "Comprimidos" ,
"concentracion" : "500mg" ,
"titular" : "Laboratorios Farma SA" ,
"estado" : "Autorizado" ,
"numero_registro" : "65123" ,
"enlace" : "https://cima.aemps.es/cima/..."
}
]
Schema: MedRecord (types.py:4-14 )
Example:
curl -X GET "https://api.vigia.app/api/v1/regulators/search?q=paracetamol&max_items=10" \
-H "Authorization: Bearer <token>"
Search Specific Agency
Query a single regulatory agency.
GET /api/v1/regulators/search/{agency}?q={query}&max_items={limit}
Parameters:
Parameter Type Required Description agencystring Yes Agency code: fda, ema, aemps, digemid, etc. qstring Yes Search query max_itemsinteger No Maximum results (default: 50)
Supported Agencies:
Code Agency Country/Region fdaFood and Drug Administration United States emaEuropean Medicines Agency European Union aempsAgencia Española de Medicamentos Spain digemidDirección General de Medicamentos Peru invimaInstituto Nacional de Vigilancia Colombia anvisaAgência Nacional de Vigilância Sanitária Brazil anmatAdministración Nacional de Medicamentos Argentina
Example:
cURL - FDA Only
Python - EMA Only
JavaScript - DIGEMID Only
curl -X GET "https://api.vigia.app/api/v1/regulators/search/fda?q=ibuprofen&max_items=25" \
-H "Authorization: Bearer <token>"
FDA Integration
Direct access to FDA medical device recalls and safety communications.
Base Path: /api/v1/fda
Features:
Medical device recalls
Early alerts and safety communications
Automatic English-to-Spanish translation
AI-powered product categorization (when GEMINI_API_KEY configured)
Search FDA
GET /api/v1/fda/search?q={query}&max_results={limit}
Parameters:
Parameter Type Required Description qstring Yes Search term (device name, IFA) in Spanish or English max_resultsinteger No Max results (1-25, default: 10)
Response:
[
{
"titulo" : "Alerta temprana para el sistema de acceso vascular WATCHMAN" ,
"medicamento" : "Sistema de acceso \n WATCHMAN" ,
"evento" : "El dispositivo puede desprenderse durante el procedimiento, causando complicaciones vasculares graves." ,
"url" : "https://www.fda.gov/medical-devices/medical-device-recalls/..." ,
"fecha_publicada" : "2024-08-05T16:00:00Z"
}
]
Schema: FDAItem
Field Type Description titulostring Translated alert title (Spanish) medicamentostring Generic device type + brand (multiline) eventostring Event description / reason for recall urlstring Source URL on FDA website fecha_publicadastring | null Publication date (ISO 8601)
Example:
curl -X GET "https://api.vigia.app/api/v1/fda/search?q=stent&max_results=5" \
-H "Authorization: Bearer <token>"
Translation:
All FDA content is automatically translated from English to Spanish using deep_translator:
Title: Translated and cleaned
Event: Summarized (1-3 sentences)
Device Type: Mapped to Spanish generic terms
AI Enhancement:
When GEMINI_API_KEY is configured, Gemini 1.5 Flash refines:
Generic device categorization
Brand/model extraction
Event summarization
Implementation: backend/app/services/fda.py
VigiAccess Integration
Query the WHO VigiAccess global adverse drug reaction database.
Base Path: /api/v1/vigiaccess
Search Adverse Reactions
GET /api/v1/vigiaccess/search?drug={drug}&reaction={reaction}
Parameters:
Parameter Type Required Description drugstring Yes Drug/product name reactionstring No Specific adverse reaction
Response:
{
"drug" : "Paracetamol" ,
"reactions" : [
{
"reaction" : "Hepatotoxicity" ,
"count" : 1523 ,
"countries" : 45 ,
"trend" : "Aumentando"
},
{
"reaction" : "Skin rash" ,
"count" : 892 ,
"countries" : 38 ,
"trend" : "Estable"
}
],
"total_reports" : 12456 ,
"reporting_countries" : 67
}
Example:
curl -X GET "https://api.vigia.app/api/v1/vigiaccess/search?drug=paracetamol&reaction=hepatotoxicity" \
-H "Authorization: Bearer <token>"
Product Dashboard
Get comprehensive VigiAccess statistics for a product.
GET /api/v1/vigiaccess/dashboard?product_id={id}
Response:
{
"product_id" : 123 ,
"product_name" : "Paracetamol" ,
"total_reports" : 12456 ,
"serious_reports" : 3421 ,
"countries_reporting" : 67 ,
"top_reactions" : [
{ "reaction" : "Hepatotoxicity" , "count" : 1523 },
{ "reaction" : "Allergic reaction" , "count" : 1124 }
],
"temporal_trends" : [
{ "year" : 2023 , "count" : 2341 },
{ "year" : 2024 , "count" : 2789 }
],
"geographic_distribution" : [
{ "country" : "United States" , "reports" : 3456 },
{ "country" : "United Kingdom" , "reports" : 2134 }
]
}
Features:
Global ADR statistics from 150+ countries
Comparative analysis across regions
Temporal trend analysis
Dashboard visualization data
Implementation: backend/app/routers/vigiaccess.py, backend/app/routers/vigiaccess_dashboard.py
DIGEMID Integration
Access Peru’s DIGEMID regulatory alerts and product registry.
Endpoints:
# Search DIGEMID product registry
GET /api/v1/regulators/search/digemid?q={query}
# Get DIGEMID alerts via surveillance
GET /api/v1/surveillance/results?scope=national & fuente = DIGEMID
Data Sources:
Alertas Sanitarias: Health alerts and recalls
RAM (Reacciones Adversas): Adverse reaction reports
Registro Sanitario: Product authorization registry
Example:
import requests
# Search product registry
response = requests.get(
"https://api.vigia.app/api/v1/regulators/search/digemid" ,
params = { "q" : "ibuprofeno" },
headers = { "Authorization" : f "Bearer { token } " }
)
products = response.json()
# Get recent DIGEMID alerts
response = requests.get(
"https://api.vigia.app/api/v1/surveillance/results" ,
params = {
"scope" : "national" ,
"query" : "DIGEMID" ,
"limit" : 20
},
headers = { "Authorization" : f "Bearer { token } " }
)
alerts = response.json()[ "items" ]
EMA Integration
European Medicines Agency safety updates and product information.
Endpoints:
# Search EMA via regulators API
GET /api/v1/regulators/search/ema?q={query}
# Get EMA alerts via surveillance
GET /api/v1/surveillance/results?scope=external & fuente = EMA
Data Sources:
Safety Updates: Pharmacovigilance announcements
EPAR (European Public Assessment Reports): Product assessments
Direct Healthcare Professional Communications (DHPC): Urgent safety alerts
Example:
# Search EMA products
curl -X GET "https://api.vigia.app/api/v1/regulators/search/ema?q=insulin&max_items=10" \
-H "Authorization: Bearer <token>"
# Get recent EMA safety updates
curl -X GET "https://api.vigia.app/api/v1/surveillance/results?scope=external&query=EMA&severity=Alta" \
-H "Authorization: Bearer <token>"
Data Enrichment Pipeline
VIGIA enhances regulatory data through a multi-stage pipeline:
Raw Data Extraction
Scrape HTML from regulatory websites
Translation
Translate English content to Spanish using deep_translator
Product Normalization
Map brand names to generic device/drug types
AI Enhancement (Optional)
Use Gemini 1.5 Flash to refine categorization and summarize events
Storage
Store normalized data in SurveillanceItem model
Translation Service
Implementation: backend/app/services/fda.py:45-73
from deep_translator import GoogleTranslator
from functools import lru_cache
@lru_cache ( maxsize = 4096 )
def translate_to_spanish ( text : str ) -> str :
"""Translate English to Spanish with caching."""
if len (text) <= 4500 :
return GoogleTranslator( source = "auto" , target = "es" ).translate(text)
# Split long texts by sentences
parts = re.split( r " (?<= [ \.\? ! ] ) \s + " , text)
translated_parts = []
for part in parts:
translated_parts.append(
GoogleTranslator( source = "auto" , target = "es" ).translate(part)
)
return " " .join(translated_parts)
Product Normalization
Generic Synonyms: backend/app/services/fda.py:150-180
Maps English device terms to Spanish categories:
GENERIC_SYNONYMS = [
(re.compile( r " \b ( catheter | ablation \s + catheter ) \b " , re.I), "Catéter" ),
(re.compile( r " \b ( stent | endoprosthesis ) \b " , re.I), "Stent vascular" ),
(re.compile( r " \b ( glucose \s + monitor | cgm ) \b " , re.I), "Monitor de glucosa (CGM)" ),
(re.compile( r " \b ( pacemaker ) \b " , re.I), "Marcapasos" ),
(re.compile( r " \b ( defibrillator ) \b " , re.I), "Desfibrilador" ),
]
Brand Detection: backend/app/services/fda.py:190-210
Extracts brand names using pattern matching:
BRAND_PATTERN = re.compile( r " \b ([ A-Z ][ A-Z0-9 \- ] {3,} ) \b " )
BRAND_STOP_WORDS = { "ACCESS" , "SYSTEM" , "CATHETER" , "DEVICE" , "PUMP" }
def extract_brand ( text : str ) -> str :
for match in BRAND_PATTERN .finditer(text):
candidate = match.group( 1 )
if candidate not in BRAND_STOP_WORDS :
return candidate
return ""
AI Enhancement (Gemini)
Implementation: backend/app/services/fda.py:220-270
When GEMINI_API_KEY is configured:
import google.generativeai as genai
def refine_with_ai ( raw_data : dict ) -> dict :
"""
Use Gemini 1.5 Flash to normalize fields.
Returns:
{
"titulo_es": "Translated and cleaned title",
"evento_es": "1-3 sentence event summary",
"producto_generico_es": "Generic device type",
"marca_o_linea": "Brand/series if clear",
"modelo_o_variante": "Model/lot if adds value"
}
"""
model = genai.GenerativeModel( "gemini-1.5-flash" )
prompt = f """
You are a regulatory analyst preparing health reports in SPANISH.
Return STRICT JSON with this form:
{{
"titulo_es": "...",
"evento_es": "...",
"producto_generico_es": "...",
"marca_o_linea": "...",
"modelo_o_variante": "..."
}}
Data:
- title_en: { raw_data[ 'title_en' ] }
- reason_en: { raw_data[ 'reason_en' ] }
- product_candidates: { raw_data[ 'product_candidates' ] }
"""
response = model.generate_content(prompt)
return json.loads(response.text)
Comparison: Surveillance vs Direct Query
Feature Scheduled Surveillance Direct Query (Regulators API) Data Freshness Depends on schedule (weekly/bi-weekly) Real-time Coverage All configured sources Single agency per request Storage Persisted in database Not stored Filtering Advanced (severity, trends, etc.) Basic (name search) Reports Email reports with attachments API response only Use Case Continuous monitoring, trend analysis Ad-hoc product lookup
When to Use Surveillance:
Automated weekly/bi-weekly monitoring
Historical trend analysis
Severity-based filtering
Automated email reports
When to Use Direct Query:
Immediate product verification
Registration status lookup
One-time investigation
Real-time alert validation
Configuration
Environment Variables
# Optional: AI enhancement for FDA scraping
GEMINI_API_KEY = your_gemini_api_key_here
# Regulator API configuration
REQUEST_TIMEOUT = 25 # seconds
MAX_RETRIES = 2
Scraper Limits
Implementation: backend/app/services/fda.py:25-30
INDEX_LIMIT = 60 # Max detail pages to scrape from index
MIN_EVENT_CHARS = 120 # Minimum paragraph length for event
REQUEST_TIMEOUT = 25 # HTTP request timeout (seconds)
Error Handling
HTTP Errors
// 404 Not Found
{
"detail" : "Agency 'invalid_agency' not found"
}
// 400 Bad Request
{
"detail" : "Query parameter 'q' is required"
}
// 502 Bad Gateway
{
"detail" : "FDA website unavailable"
}
Graceful Degradation
Scrapers include fallback strategies:
try :
# Try AI-powered extraction
data = extract_with_gemini(raw_html)
except Exception :
try :
# Fallback to rule-based extraction
data = extract_with_rules(raw_html)
except Exception :
# Final fallback: basic translation only
data = translate_basic(raw_html)
Rate Limits
External API Limits:
FDA: No official rate limit, but excessive requests may be blocked
EMA: No official rate limit
VigiAccess: Public API with soft limit (approx. 100 req/hour)
Translation (Google Translate): Free tier limited to 500K chars/month
Recommendation: Use scheduled surveillance for continuous monitoring. Reserve direct queries for urgent/ad-hoc needs.
Best Practices
Cache Results Store frequently-queried products to reduce API calls. Use surveillance for continuous monitoring instead of repeated direct queries.
Combine Approaches Surveillance: Weekly monitoring for trendsDirect Query: Immediate verification during case intake
Monitor Translation Costs Deep Translator uses Google Translate free tier. Enable GEMINI_API_KEY for AI enhancement (requires paid API key).
Handle Errors Gracefully Regulatory websites may be temporarily unavailable. Implement retry logic and fallback to cached data.
Integration Examples
Product Verification During Case Intake
import requests
def verify_product_registration ( product_name : str , country : str , token : str ) -> dict :
"""
Verify product is registered with local regulatory authority.
"""
agency_map = {
"Peru" : "digemid" ,
"United States" : "fda" ,
"Spain" : "aemps" ,
"European Union" : "ema"
}
agency = agency_map.get(country)
if not agency:
return { "verified" : False , "reason" : "Unsupported country" }
response = requests.get(
f "https://api.vigia.app/api/v1/regulators/search/ { agency } " ,
params = { "q" : product_name, "max_items" : 5 },
headers = { "Authorization" : f "Bearer { token } " }
)
if response.status_code == 200 :
results = response.json()
if results:
return {
"verified" : True ,
"registration_number" : results[ 0 ].get( "numero_registro" ),
"holder" : results[ 0 ].get( "titular" ),
"status" : results[ 0 ].get( "estado" )
}
return { "verified" : False , "reason" : "Product not found in registry" }
# Usage
result = verify_product_registration( "Paracetamol 500mg" , "Peru" , token)
if result[ "verified" ]:
print ( f "Product verified: { result[ 'registration_number' ] } " )
else :
print ( f "Verification failed: { result[ 'reason' ] } " )
Cross-Reference Surveillance Alerts
import requests
def cross_reference_alerts ( drug_name : str , token : str ) -> dict :
"""
Check if drug has active alerts across multiple sources.
"""
# 1. Check surveillance database
surv_response = requests.get(
"https://api.vigia.app/api/v1/surveillance/results" ,
params = {
"scope" : "external" ,
"medicamento" : drug_name,
"severity" : "Alta" ,
"limit" : 10
},
headers = { "Authorization" : f "Bearer { token } " }
)
surveillance_alerts = surv_response.json()[ "items" ]
# 2. Query FDA directly for latest info
fda_response = requests.get(
"https://api.vigia.app/api/v1/fda/search" ,
params = { "q" : drug_name, "max_results" : 5 },
headers = { "Authorization" : f "Bearer { token } " }
)
fda_alerts = fda_response.json()
# 3. Check VigiAccess for global ADR trends
vigiaccess_response = requests.get(
"https://api.vigia.app/api/v1/vigiaccess/search" ,
params = { "drug" : drug_name},
headers = { "Authorization" : f "Bearer { token } " }
)
vigiaccess_data = vigiaccess_response.json()
return {
"drug" : drug_name,
"surveillance_alerts" : len (surveillance_alerts),
"fda_alerts" : len (fda_alerts),
"vigiaccess_reports" : vigiaccess_data.get( "total_reports" , 0 ),
"has_active_alerts" : len (surveillance_alerts) > 0 or len (fda_alerts) > 0
}
# Usage
result = cross_reference_alerts( "Paracetamol" , token)
if result[ "has_active_alerts" ]:
print ( f "WARNING: { result[ 'surveillance_alerts' ] } surveillance alerts found" )
print ( f "FDA alerts: { result[ 'fda_alerts' ] } " )
print ( f "Global VigiAccess reports: { result[ 'vigiaccess_reports' ] } " )
FDA Integration Detailed FDA scraper documentation
EMA Integration European Medicines Agency integration
DIGEMID Peru regulatory authority
VigiAccess WHO global database
Surveillance Overview Main surveillance API
Schedule Management Configure automated scraping
Code References
Component File Location Regulators Router backend/app/routers/regulators.py:1-16FDA Scraper backend/app/services/fda.pyRegulator Types backend/app/services/regulators/types.py:4-14Search Services backend/app/services/regulators/scrape_regulators.pyVigiAccess Router backend/app/routers/vigiaccess.pyVigiAccess Dashboard backend/app/routers/vigiaccess_dashboard.py