Tutorial

How to Add Search to a Contract AI Workflow

Ground contract analysis AI with live search data. Pull regulatory updates, precedent cases, and company context for better contract review.

Add search grounding to a contract AI workflow by querying for regulatory updates, company background, and industry-specific precedents before or during contract analysis. Contract review AI tools often work with static training data that misses recent regulatory changes, company-specific risks, and current market conditions. A search enrichment step that runs before analysis gives the AI current context about the counterparty, relevant regulations, and recent enforcement actions, producing more accurate risk assessments.

Prerequisites

  • Python 3.8+ installed
  • requests library installed
  • A Scavio API key from scavio.dev
  • A contract text or key clauses to analyze

Walkthrough

Step 1: Extract key entities from contract

Identify company names, jurisdictions, and clause types that need search enrichment.

Python
import os, requests, re

API_KEY = os.environ['SCAVIO_API_KEY']

def extract_entities(contract_text: str) -> dict:
    """Extract searchable entities from contract text."""
    entities = {
        'companies': [],
        'jurisdictions': [],
        'clause_types': [],
    }
    # Simple company name extraction (between quotes or after 'between')
    company_patterns = re.findall(r'"([A-Z][^"]{2,50})"', contract_text)
    entities['companies'] = list(set(company_patterns))[:5]
    # Jurisdiction extraction
    jurisdiction_keywords = ['governed by the laws of', 'jurisdiction of', 'state of', 'courts of']
    for kw in jurisdiction_keywords:
        match = re.search(kw + r'\s+([A-Z][\w\s]{2,30})', contract_text)
        if match:
            entities['jurisdictions'].append(match.group(1).strip())
    # Clause type detection
    clause_keywords = {'indemnification': 'indemnif', 'non-compete': 'non-compete',
                       'termination': 'terminat', 'liability': 'liabilit', 'confidentiality': 'confidential'}
    for clause, keyword in clause_keywords.items():
        if keyword in contract_text.lower():
            entities['clause_types'].append(clause)
    return entities

sample = 'Agreement between "Acme Corp" and "Beta LLC" governed by the laws of Delaware. Includes indemnification and non-compete clauses.'
entities = extract_entities(sample)
print(f"Companies: {entities['companies']}")
print(f"Jurisdictions: {entities['jurisdictions']}")
print(f"Clauses: {entities['clause_types']}")

Step 2: Search for company risk signals

Research each counterparty for lawsuits, enforcement actions, and recent news.

Python
def search_company_risk(company: str) -> dict:
    queries = [
        f'{company} lawsuit 2026',
        f'{company} SEC enforcement',
        f'{company} bankruptcy risk',
    ]
    risk_signals = {'company': company, 'lawsuits': [], 'enforcement': [], 'news': []}
    for query in queries:
        resp = requests.post('https://api.scavio.dev/api/v1/search',
            headers={'x-api-key': API_KEY},
            json={'platform': 'google', 'query': query}, timeout=15)
        results = resp.json().get('organic_results', [])
        for r in results[:3]:
            title = r.get('title', '')
            if any(w in title.lower() for w in ['lawsuit', 'sued', 'settlement', 'verdict']):
                risk_signals['lawsuits'].append(title)
            elif any(w in title.lower() for w in ['sec', 'enforcement', 'fine', 'penalty']):
                risk_signals['enforcement'].append(title)
            else:
                risk_signals['news'].append(title)
    return risk_signals

risk = search_company_risk('Acme Corp')
print(f"Lawsuits: {len(risk['lawsuits'])}")
print(f"Enforcement: {len(risk['enforcement'])}")

Step 3: Search regulatory updates

Pull recent regulatory changes relevant to the contract's jurisdiction and clause types.

Python
def search_regulatory(jurisdiction: str, clause_types: list) -> list:
    updates = []
    for clause in clause_types:
        query = f'{clause} clause regulation {jurisdiction} 2026'
        resp = requests.post('https://api.scavio.dev/api/v1/search',
            headers={'x-api-key': API_KEY},
            json={'platform': 'google', 'query': query}, timeout=15)
        results = resp.json().get('organic_results', [])
        for r in results[:2]:
            updates.append({
                'clause': clause,
                'title': r.get('title', ''),
                'snippet': r.get('snippet', '')[:150],
                'url': r.get('link', ''),
            })
    return updates

updates = search_regulatory('Delaware', ['indemnification', 'non-compete'])
for u in updates:
    print(f"[{u['clause']}] {u['title'][:60]}")

Step 4: Build enrichment context

Combine all search findings into a structured context block for the contract AI.

Python
def build_contract_context(entities: dict) -> dict:
    context = {'companies': {}, 'regulatory': [], 'risk_level': 'low'}
    for company in entities.get('companies', []):
        risk = search_company_risk(company)
        context['companies'][company] = risk
        if risk['lawsuits'] or risk['enforcement']:
            context['risk_level'] = 'high' if risk['enforcement'] else 'medium'
    for jurisdiction in entities.get('jurisdictions', []):
        updates = search_regulatory(jurisdiction, entities.get('clause_types', []))
        context['regulatory'].extend(updates)
    return context

context = build_contract_context(entities)
print(f"Risk level: {context['risk_level']}")
print(f"Regulatory updates: {len(context['regulatory'])}")

Step 5: Generate enriched analysis prompt

Format the search context into a prompt section for the contract review AI.

Python
def format_analysis_prompt(contract_text: str, context: dict) -> str:
    parts = ['ENRICHMENT CONTEXT (from live search):', '']
    if context.get('risk_level') != 'low':
        parts.append(f"RISK LEVEL: {context['risk_level'].upper()}")
    for company, risk in context.get('companies', {}).items():
        parts.append(f'\nCounterparty: {company}')
        if risk['lawsuits']:
            parts.append(f"  Active litigation: {'; '.join(risk['lawsuits'][:2])}")
        if risk['enforcement']:
            parts.append(f"  Enforcement actions: {'; '.join(risk['enforcement'][:2])}")
    if context.get('regulatory'):
        parts.append('\nRecent regulatory updates:')
        for u in context['regulatory'][:3]:
            parts.append(f"  [{u['clause']}] {u['title'][:60]}")
    parts.append('')
    parts.append('CONTRACT TEXT:')
    parts.append(contract_text[:1000])
    return '\n'.join(parts)

prompt = format_analysis_prompt(sample, context)
print(prompt[:500])

Python Example

Python
import requests, os
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}

def contract_context(company, clause):
    data = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'platform': 'google', 'query': f'{company} {clause} lawsuit 2026'}).json()
    return [r.get('title', '')[:60] for r in data.get('organic_results', [])[:3]]

print(contract_context('Acme Corp', 'indemnification'))

JavaScript Example

JavaScript
const H = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
async function contractContext(company, clause) {
  const r = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: H,
    body: JSON.stringify({platform: 'google', query: `${company} ${clause} lawsuit 2026`})
  });
  return ((await r.json()).organic_results || []).slice(0, 3).map(r => (r.title || '').slice(0, 60));
}
contractContext('Acme Corp', 'indemnification').then(console.log);

Expected Output

JSON
A contract AI workflow enriched with live search data including counterparty risk signals, regulatory updates, and enforcement actions for more accurate contract review.

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.8+ installed. requests library installed. A Scavio API key from scavio.dev. A contract text or key clauses to analyze. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Ground contract analysis AI with live search data. Pull regulatory updates, precedent cases, and company context for better contract review.