Retool le permite crear paneles internos sin código de interfaz. Este tutorial conecta a Scavio como fuente de datos para crear un panel de SEO con seguimiento de clasificación, monitoreo de funciones SERP y comparación de la competencia. Retool maneja la interfaz de usuario mientras que Scavio proporciona datos SERP en tiempo real a $0,005/consulta.
Requisitos previos
- Una cuenta Retool (el nivel gratuito funciona)
- Una clave API de Scavio de scavio.dev
- Conocimientos básicos de SQL o JavaScript
Guia paso a paso
Paso 1: Configurar Scavio como recurso API REST de Retool
Agregue Scavio como recurso de API REST en Retool para que las consultas puedan llamarlo directamente.
// In Retool: Settings > Resources > Add Resource > REST API
// Name: Scavio Search API
// Base URL: https://api.scavio.dev/api/v1
// Headers:
// x-api-key: {{SCAVIO_API_KEY}}
// Content-Type: application/json
// Test query in Retool Query Editor:
// Method: POST
// URL: /search
// Body:
{
"query": "{{ textInput1.value }}",
"country_code": "us"
}
// Retool will show the response with organic_results, people_also_ask, etc.
// Map these to table and chart components.
// For server-side testing:
import os, requests
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': 'best search api 2026', 'country_code': 'us'}).json()
print(f'Organic results: {len(data.get("organic_results", []))}')
print(f'PAA questions: {len(data.get("people_also_ask", []))}')
print(f'Has featured snippet: {bool(data.get("featured_snippet"))}')Paso 2: Cree la vista de seguimiento de clasificación
Cree una tabla Retool que muestre las posiciones y tendencias de las palabras clave a lo largo del tiempo.
import os, requests, json
from datetime import datetime
API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}
def retool_rank_data(keywords, domain):
"""Generate data formatted for Retool table component."""
rows = []
for kw in keywords:
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': kw, 'country_code': 'us'}, timeout=10).json()
organic = data.get('organic_results', [])
pos = next((i+1 for i, r in enumerate(organic) if domain in r.get('link', '')), None)
featured = data.get('featured_snippet', {})
rows.append({
'keyword': kw,
'position': pos,
'in_top3': pos is not None and pos <= 3,
'in_featured': domain in featured.get('displayed_link', ''),
'competitor_1': organic[0].get('displayed_link', '') if organic else '',
'paa_count': len(data.get('people_also_ask', [])),
'date': datetime.now().strftime('%Y-%m-%d'),
})
return rows
keywords = ['search api python', 'mcp search tool', 'serp api pricing', 'web search api free tier']
rows = retool_rank_data(keywords, 'scavio.dev')
print(f'Retool table data: {len(rows)} rows')
for r in rows:
pos = f'#{r["position"]}' if r['position'] else '-'
print(f' {r["keyword"]:35} | {pos:5} | Top 3: {r["in_top3"]}')
print(f'\nCost: ${len(keywords) * 0.005:.3f}')Paso 3: Agregar monitoreo de funciones SERP
Realice un seguimiento de qué funciones SERP aparecen para cada palabra clave y cómo cambian.
def serp_features_data(keywords):
"""Extract SERP features for Retool chart components."""
features = []
for kw in keywords:
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': kw, 'country_code': 'us'}, timeout=10).json()
feat = {
'keyword': kw,
'has_ai_overview': bool(data.get('ai_overview', data.get('answer_box'))),
'has_featured_snippet': bool(data.get('featured_snippet')),
'has_paa': len(data.get('people_also_ask', [])) > 0,
'paa_count': len(data.get('people_also_ask', [])),
'organic_count': len(data.get('organic_results', [])),
'has_knowledge_graph': bool(data.get('knowledge_graph')),
}
features.append(feat)
# Summary for Retool pie chart
ai_count = sum(1 for f in features if f['has_ai_overview'])
fs_count = sum(1 for f in features if f['has_featured_snippet'])
paa_count = sum(1 for f in features if f['has_paa'])
print(f'\n=== SERP Features Summary (for Retool) ===')
print(f' Keywords scanned: {len(features)}')
print(f' AI Overview: {ai_count}/{len(features)} ({ai_count/len(features)*100:.0f}%)')
print(f' Featured Snippet: {fs_count}/{len(features)} ({fs_count/len(features)*100:.0f}%)')
print(f' People Also Ask: {paa_count}/{len(features)} ({paa_count/len(features)*100:.0f}%)')
print(f'\n Retool: Bind this data to a pie chart component')
print(f' Cost: ${len(keywords) * 0.005:.3f}/scan')
return features
serp_features_data(keywords)Ejemplo en Python
import os, requests
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
def retool_data(keyword):
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json={'query': keyword, 'country_code': 'us'}, timeout=10).json()
organic = data.get('organic_results', [])[:5]
return [{'pos': i+1, 'domain': r.get('displayed_link', ''), 'title': r['title'][:40]} for i, r in enumerate(organic)]
for r in retool_data('best search api'):
print(f'#{r["pos"]} {r["domain"]:25} {r["title"]}')Ejemplo en JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: SH,
body: JSON.stringify({ query: 'best search api', country_code: 'us' })
}).then(r => r.json());
const rows = (data.organic_results || []).slice(0, 5).map((r, i) => ({
position: i + 1, domain: r.displayed_link, title: r.title
}));
console.log(JSON.stringify(rows, null, 2));Salida esperada
Retool table data: 4 rows
search api python | #3 | Top 3: True
mcp search tool | #2 | Top 3: True
serp api pricing | #5 | Top 3: False
web search api free tier | #4 | Top 3: False
Cost: $0.020
=== SERP Features Summary (for Retool) ===
Keywords scanned: 4
AI Overview: 3/4 (75%)
Featured Snippet: 2/4 (50%)
People Also Ask: 4/4 (100%)
Cost: $0.020/scan