To integrate SpyFu with V0 by Vercel, generate a competitor analysis dashboard UI with V0, create a Next.js API route that fetches keyword and PPC intelligence from the SpyFu API, store your SpyFu API credentials in Vercel environment variables, and deploy. Your dashboard will show competitors' top keywords, ad spend estimates, and organic ranking positions.
Build Competitive SEO Intelligence Dashboards with SpyFu and V0
SpyFu's core value proposition is revealing what your competitors are spending on Google Ads and which keywords are driving their organic traffic — data they'd rather you didn't have. Its API makes this intelligence programmable: you can fetch a domain's top paid keywords, see ad copy variations over time, compare multiple domains' keyword overlap, and track ranking positions. V0 can generate the dashboard UI to visualize this data in minutes; the integration challenge is connecting that UI to real SpyFu data through a secure API proxy.
The SpyFu API is REST-based and uses simple key-based authentication. Most endpoints accept a domain parameter and return structured data about that domain's SEO and PPC profile. The API is organized around domains (competitor profile endpoints), keywords (keyword intelligence endpoints), and ads (ad copy and spend endpoints). Response data includes numeric estimates for monthly search volume, cost per click, organic ranking positions, and estimated monthly ad spend — all derived from SpyFu's proprietary data models.
This integration is valuable for digital marketing agencies building client reporting tools, SaaS companies monitoring their competitive landscape, and founders who want to understand competitors' keyword strategies before investing in content or paid campaigns. The V0-generated dashboard can show real-time competitive snapshots that would take hours to compile manually from SpyFu's web interface.
Integration method
SpyFu integrates with V0-generated Next.js apps through server-side API routes that proxy requests to the SpyFu REST API. Your SpyFu API credentials are stored as server-only Vercel environment variables and never exposed to the browser. The V0-generated dashboard components fetch competitor intelligence data from your API routes and display keyword rankings, PPC data, and domain comparisons.
Prerequisites
- A SpyFu account with API access — API credentials are available on SpyFu's Professional or Team plans at spyfu.com/api
- Your SpyFu API username and secret key — found in your SpyFu account under API settings
- A V0 account at v0.dev to generate the dashboard UI
- A Vercel account to deploy the Next.js app and store SpyFu credentials as environment variables
- Basic understanding of SEO and PPC concepts to interpret the SpyFu API response data correctly
Step-by-step guide
Generate the Competitor Analysis Dashboard with V0
Generate the Competitor Analysis Dashboard with V0
Open V0 at v0.dev and describe the competitive SEO dashboard you need. SpyFu data is inherently tabular and numerical — keyword lists with rankings, CPC values, and traffic estimates. V0 does well with data-heavy dashboard layouts using sortable tables and summary stat cards. Ask V0 for specific components: a domain search input that triggers a fetch to your API route, summary cards showing key metrics (total keywords, monthly traffic estimate, ad spend), and data tables for organic and paid keywords. V0 will generate a React client component that manages the domain input state and fetches from /api/spyfu/domain on form submission. Review the generated mock data structure in V0's component — the column names and data shapes will inform how you need to structure your API route's response. Pay attention to how V0 renders the tables: if it generates a generic Table component from shadcn/ui, note the data prop structure expected. Push the generated project to GitHub using V0's Git panel to enable Vercel auto-deployment.
Build a competitor SEO analysis dashboard with a search bar at the top for entering a competitor domain (e.g., competitor.com), a loading state while data is fetched, and four metric cards showing Total Organic Keywords, Total Paid Keywords, Monthly Traffic Estimate, and Estimated Monthly Ad Spend. Below the cards, show a sortable table of top 20 organic keywords with columns: Keyword, Monthly Searches, Position, Traffic. Next to it, a table of top 20 paid keywords with: Keyword, Monthly Searches, Avg CPC, Monthly Budget. Data comes from /api/spyfu/domain. Dark sidebar, white content.
Paste this in V0 chat
Pro tip: Ask V0 to add a debounce to the domain input or a search button (rather than searching on every keystroke) — SpyFu API calls cost against your plan's monthly quota, so triggering a search only on explicit submission is better than instant search.
Expected result: A professional competitor analysis dashboard renders in V0's preview with sample keyword tables, metric cards, and a domain search input — structured to receive real SpyFu API data.
Create the SpyFu Domain Analysis API Route
Create the SpyFu Domain Analysis API Route
Create the API route that calls SpyFu's REST API for domain analysis data. The SpyFu API base URL is https://www.spyfu.com/apis/domain_api/v2/ for domain data. Authentication uses HTTP Basic Auth with your username and secret key. The main endpoints you need are the domain overview endpoint (which returns summary stats like total keywords and estimated traffic) and the top keywords endpoint (which returns lists of the domain's top organic and paid keywords with their metrics). The API uses query parameters including q (the domain to analyze) and api_key for some endpoints. Check SpyFu's API documentation for the exact parameter names for your plan tier — the Professional API and Enterprise API have slightly different endpoint structures. Your API route receives a domain query parameter from the component, calls SpyFu, and returns transformed data. SpyFu API responses can be large — apply a reasonable page size limit (top 20-50 keywords) to keep response times fast. The route should validate the domain format before sending it to SpyFu to avoid wasting API calls on invalid input.
1// app/api/spyfu/domain/route.ts2import { NextRequest, NextResponse } from 'next/server';34const SPYFU_API_BASE = 'https://www.spyfu.com/apis';56async function spyfuFetch(path: string): Promise<Response> {7 const apiKey = process.env.SPYFU_SECRET_KEY;8 const username = process.env.SPYFU_USERNAME;910 if (!apiKey || !username) {11 throw new Error('SpyFu credentials not configured');12 }1314 const credentials = Buffer.from(`${username}:${apiKey}`).toString('base64');1516 return fetch(`${SPYFU_API_BASE}${path}`, {17 headers: {18 Authorization: `Basic ${credentials}`,19 Accept: 'application/json',20 },21 next: { revalidate: 3600 }, // Cache for 1 hour - SpyFu data doesn't change frequently22 });23}2425export async function GET(request: NextRequest) {26 const { searchParams } = new URL(request.url);27 const domain = searchParams.get('domain');2829 if (!domain) {30 return NextResponse.json({ error: 'domain parameter is required' }, { status: 400 });31 }3233 // Validate domain format34 const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/;35 if (!domainRegex.test(domain)) {36 return NextResponse.json({ error: 'Invalid domain format' }, { status: 400 });37 }3839 try {40 // Fetch domain overview41 const [overviewRes, organicRes, paidRes] = await Promise.all([42 spyfuFetch(`/domain_api/v2/stats/json?q=${domain}&countryCode=US`),43 spyfuFetch(`/domain_api/v2/organic_keywords/json?q=${domain}&pageSize=20&countryCode=US`),44 spyfuFetch(`/domain_api/v2/paid_keywords/json?q=${domain}&pageSize=20&countryCode=US`),45 ]);4647 if (!overviewRes.ok) {48 throw new Error(`SpyFu API error: ${overviewRes.status}`);49 }5051 const [overview, organicData, paidData] = await Promise.all([52 overviewRes.json(),53 organicRes.ok ? organicRes.json() : { results: [] },54 paidRes.ok ? paidRes.json() : { results: [] },55 ]);5657 return NextResponse.json({58 domain,59 summary: {60 totalOrganicKeywords: overview.totalOrganicKeywords || 0,61 totalPaidKeywords: overview.totalPaidKeywords || 0,62 monthlyOrganicClicks: overview.monthlyOrganicClicks || 0,63 monthlyBudget: overview.monthlyBudget || 0,64 domainStrength: overview.domainStrength || 0,65 },66 organicKeywords: (organicData.results || []).map((kw: Record<string, unknown>) => ({67 keyword: kw.keyword,68 monthlySearches: kw.searchVolume || 0,69 position: kw.rankingPosition || 0,70 traffic: kw.clicksPerMonth || 0,71 })),72 paidKeywords: (paidData.results || []).map((kw: Record<string, unknown>) => ({73 keyword: kw.keyword,74 monthlySearches: kw.searchVolume || 0,75 avgCpc: kw.avgAdWordsAdsCPC || 0,76 monthlyBudget: kw.monthlyBudget || 0,77 })),78 });79 } catch (error) {80 console.error('SpyFu API error:', error);81 return NextResponse.json(82 { error: 'Failed to fetch SpyFu data' },83 { status: 500 }84 );85 }86}Pro tip: Use Promise.all to fetch the domain overview, organic keywords, and paid keywords simultaneously rather than sequentially. This reduces dashboard load time from ~3 seconds to ~1 second since all three SpyFu API calls can execute in parallel.
Expected result: Calling GET /api/spyfu/domain?domain=competitor.com returns a structured JSON object with domain summary stats, organic keyword list, and paid keyword list sourced from SpyFu.
Connect Dashboard Components to the API Route
Connect Dashboard Components to the API Route
Update your V0-generated dashboard components to fetch from the /api/spyfu/domain route when the user submits a domain. The component should manage three states: idle (before any search), loading (while fetching), and data (once the response arrives). The form's submit handler should call fetch('/api/spyfu/domain?domain=' + encodeURIComponent(domain)) and update state based on the response. Map the returned data objects to your table components' expected format. The keyword tables should be sortable — your component can use React's useState to track the current sort column and direction, sorting the data array before rendering. Add a formatted currency display for the ad spend values (the monthlyBudget field is in dollars) and format large numbers with commas for readability. If V0 generated generic table components, the data-to-table mapping should be straightforward. If V0 generated more specific components with hardcoded column definitions, update those definitions to match the actual SpyFu data fields your API route returns.
Update the competitor dashboard to accept a domain input, call GET /api/spyfu/domain?domain={input} on form submit, display loading skeletons while fetching, and populate all four metric cards and both keyword tables with the returned data. Format monthlyBudget values as currency ($1,234) and add K/M suffixes to large numbers (1.2M searches). Make the keyword tables sortable by clicking column headers. Show an error message if the domain returns no data.
Paste this in V0 chat
Pro tip: Cache SpyFu results in component state so users can switch between multiple analyzed domains without re-fetching. Use a Map keyed by domain name to store previously fetched results and return cached data instantly when the same domain is searched again.
Expected result: Entering a domain in the dashboard search bar triggers a SpyFu API lookup, displays loading states, and populates the metric cards and keyword tables with real competitor data from SpyFu.
Configure Credentials in Vercel and Deploy
Configure Credentials in Vercel and Deploy
Push your project to GitHub and add SpyFu credentials to Vercel. Open the Vercel Dashboard, go to your project → Settings → Environment Variables. Add SPYFU_USERNAME with your SpyFu account username (usually your email address) and SPYFU_SECRET_KEY with your API secret key from SpyFu's API settings page. Neither should have the NEXT_PUBLIC_ prefix — both are server-side secrets. Set them for Production, Preview, and Development environments. After saving, trigger a deployment from the Deployments tab. Once deployed, test by entering a well-known competitor domain (try your own company's website first to verify the data looks reasonable). Check the Vercel Function Logs if you encounter errors — they'll show the raw error from SpyFu's API, which is typically more helpful than the generic error message returned to the client. SpyFu API plans have monthly call limits, so monitor your usage in SpyFu's account dashboard to ensure you're not approaching the limit during heavy development testing.
Pro tip: Add the domain search term to the page URL as a query parameter (?domain=competitor.com) so users can bookmark and share specific competitor analyses. Use Next.js useSearchParams and useRouter to read and update the URL without a page reload.
Expected result: Your deployed Vercel app's competitor dashboard fetches real SpyFu data for any domain entered, with credentials securely stored in Vercel environment variables and never visible to users.
Common use cases
Competitor Keyword Analysis Dashboard
An internal dashboard where users enter a competitor's domain and see their top organic and paid keywords, estimated monthly traffic, average ad spend, and ranking positions. The data helps identify keyword opportunities and gaps in the competitor's strategy.
Create a competitor analysis dashboard with a domain search input at the top, a summary row showing total keywords, estimated monthly visitors, average ad spend, and domain strength score. Below, show two tables side by side: 'Top Organic Keywords' and 'Top Paid Keywords', each with columns for keyword, monthly searches, position/CPC, and traffic. Data loads from /api/spyfu/domain. Use a dark professional design.
Copy this prompt to try it in V0
Side-by-Side Competitor Comparison
A comparison tool that accepts two domains and shows their keyword overlap, unique keywords for each, and relative strengths in paid vs organic search. Visualizes the competitive gap with bar charts and keyword Venn diagram data.
Build a domain comparison page with two domain inputs labeled 'Your Domain' and 'Competitor Domain', a keyword overlap meter showing shared keywords percentage, two columns of metrics (organic keywords, paid keywords, monthly traffic estimate, ad spend estimate), and a table of keywords where both domains rank. Fetch from /api/spyfu/compare. Use a clean split-screen layout.
Copy this prompt to try it in V0
Ad Intelligence Monitor
A page that tracks a competitor's Google Ads history — showing current ad copy, keywords they bid on, and estimated monthly ad spend over time. Useful for monitoring competitors' messaging changes and identifying high-value keywords they're investing in.
Design an ad intelligence page for a competitor domain showing a timeline of monthly estimated ad spend as a line chart, current active ad copy examples in card format, top 10 keywords by estimated spend in a sortable table, and a 'Keyword Overlap' section showing keywords both you and the competitor bid on. Fetch data from /api/spyfu/ads. Professional marketing dashboard aesthetic.
Copy this prompt to try it in V0
Troubleshooting
SpyFu API returns 403 Forbidden
Cause: Your SpyFu API credentials are incorrect, your plan doesn't include API access, or you've exceeded your monthly API call quota for the plan tier.
Solution: Verify credentials in SpyFu account settings. Confirm your plan includes API access (Professional or higher). Check your API usage dashboard in SpyFu to see if you've hit monthly limits. Contact SpyFu support to confirm API access is enabled on your account.
API route returns empty keyword arrays for some domains
Cause: SpyFu may not have data for very small, new, or non-US domains. The API returns empty arrays rather than errors when a domain has no tracked keywords in their database.
Solution: Add an empty state to your UI for when keyword arrays are empty: 'No SpyFu data found for this domain. Try a larger domain or check that the domain is spelled correctly.' Also verify you're including the countryCode=US parameter (or the appropriate country for your target market).
Dashboard loads slowly (3-5 seconds) for each domain search
Cause: Three sequential SpyFu API calls are being made instead of parallel calls. Each call takes 500-1500ms, so sequential execution multiplies the latency.
Solution: Use Promise.all to make the overview, organic keywords, and paid keywords API calls simultaneously as shown in the route code. This reduces total latency to the time of the single slowest call rather than the sum of all three.
1// Use Promise.all for parallel fetching:2const [overviewRes, organicRes, paidRes] = await Promise.all([3 spyfuFetch(`/domain_api/v2/stats/json?q=${domain}`),4 spyfuFetch(`/domain_api/v2/organic_keywords/json?q=${domain}&pageSize=20`),5 spyfuFetch(`/domain_api/v2/paid_keywords/json?q=${domain}&pageSize=20`),6]);SPYFU_SECRET_KEY is undefined in the deployed function
Cause: The environment variable was added to Vercel after the last deployment, or it was accidentally given a NEXT_PUBLIC_ prefix which makes it undefined in server-side code for variables that don't start with that prefix.
Solution: Check Vercel Dashboard → Settings → Environment Variables. Confirm the variable name is exactly SPYFU_SECRET_KEY (no NEXT_PUBLIC_ prefix) and is set for the Production environment. Trigger a fresh redeploy after confirming the variable is correctly configured.
Best practices
- Cache SpyFu API responses for at least 1 hour using Next.js fetch caching (next: { revalidate: 3600 }) — competitor data doesn't change by the minute and caching reduces API quota usage significantly
- Validate domain input format before sending to SpyFu to avoid wasting API quota on invalid queries
- Use Promise.all for parallel API calls when fetching multiple SpyFu endpoints for the same domain analysis
- Display SpyFu's data estimates with appropriate caveats — these are estimates based on SpyFu's models, not exact figures from Google
- Add a countryCode parameter to API requests to ensure you're getting data for the market you care about (US data is the most comprehensive in SpyFu)
- Monitor your SpyFu API quota in the account dashboard during development to avoid accidentally exhausting your monthly allocation during testing
- Never hardcode SpyFu API credentials in code — always use process.env.SPYFU_SECRET_KEY in server-side API routes only
Alternatives
Use SEMrush instead of SpyFu if you need a broader all-in-one SEO platform with site audits, backlink analysis, and content tools beyond competitor keyword intelligence.
Choose Ahrefs over SpyFu if backlink analysis and link-building intelligence is more important to you than PPC competitor ad spend tracking.
Use Ubersuggest for a more affordable entry-level competitor keyword analysis tool if SpyFu's pricing is a barrier for early-stage projects.
Frequently asked questions
What SpyFu plan is required to use the API?
SpyFu's API access is available on Professional and Team plans (not the Basic plan). Professional starts around $39/month and includes a set number of API calls per month. Check spyfu.com/api for current pricing and quota details as these change periodically.
How accurate is SpyFu's data?
SpyFu provides estimates based on their own data models, not exact figures from Google. Keyword rankings tend to be accurate for established domains. Ad spend and traffic estimates are approximations — they're directionally correct and useful for competitive comparison, but shouldn't be treated as precise financial figures. SpyFu works best for identifying patterns and relative competitive positioning.
Can I track historical competitor data with the SpyFu API?
Yes. SpyFu is one of the few tools with deep historical data — some domains have keyword history going back over a decade. The API includes endpoints for historical keyword data and ad spend over time. Look for the history endpoints in SpyFu's API documentation to fetch time-series data for trend chart visualizations.
Does SpyFu cover non-US markets?
SpyFu covers multiple countries but its US database is by far the most comprehensive. Coverage for UK, Canada, and Australia is solid but smaller. Data quality for other markets varies. Always test with the countryCode parameter for your target market to assess available data before building a dashboard around it.
How do I handle SpyFu API rate limits in my dashboard?
SpyFu enforces monthly quota limits rather than per-second rate limits. Implement caching (next: { revalidate: 3600 }) to avoid re-fetching the same domain multiple times. Track your usage in SpyFu's account dashboard. If you're building a multi-user tool where different users analyze different domains, your monthly quota will deplete faster than expected.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation