Skip to main content
RapidDev - Software Development Agency
replit-integrationsStandard API Integration

How to Integrate Replit with SpyFu

To integrate Replit with SpyFu, sign up for a SpyFu API plan, get your API key from the account settings, store it in Replit Secrets (lock icon πŸ”’), and use Python or Node.js to fetch competitor keyword rankings, PPC ad history, and organic search data. Deploy on Autoscale for on-demand competitive intelligence queries.

What you'll learn

  • How to obtain a SpyFu API key from an API-enabled plan and store it in Replit Secrets
  • How to query SpyFu for a competitor domain's top keywords and organic rankings
  • How to retrieve PPC keyword data, estimated ad spend, and ad copy history for any domain
  • How to build a competitor intelligence report endpoint in Python and Node.js
  • How to handle SpyFu API pagination for large result sets
Book a free consultation
4.9Clutch rating ⭐
600+Happy partners
17+Countries served
190+Team members
Intermediate14 min read35 minutesSEOMarch 2026RapidDev Engineering Team
TL;DR

To integrate Replit with SpyFu, sign up for a SpyFu API plan, get your API key from the account settings, store it in Replit Secrets (lock icon πŸ”’), and use Python or Node.js to fetch competitor keyword rankings, PPC ad history, and organic search data. Deploy on Autoscale for on-demand competitive intelligence queries.

Why Connect Replit to the SpyFu API?

SpyFu is one of the most detailed competitor intelligence tools available, offering over 14 years of historical keyword and PPC data for millions of domains. Unlike broader SEO suites, SpyFu's core differentiator is its focus on competitor analysis β€” understanding exactly which keywords competitors rank for organically, which Google Ads they run, how much they spend on PPC, and how their rankings change over time. The SpyFu API exposes this data programmatically, enabling automated competitor tracking, agency reporting, and alerting workflows.

The SpyFu API is organized around domain-level queries. You supply a competitor's domain name and the API returns their organic keywords, monthly clicks, domain strength, PPC keywords, estimated ad spend, and ad copy text. This is useful for building automated competitive dashboards, generating client SEO reports, identifying keyword gaps between your site and competitors, and monitoring when competitors change their PPC strategy.

SpyFu API access requires a paid plan (Basic or higher) β€” the API is not available on the free tier. The API key is passed as a query parameter called 'api_key' or uses Basic auth with the key. Rate limits vary by plan. Store the key in Replit Secrets and proxy all SpyFu API calls through your Replit backend to prevent key exposure.

Integration method

Standard API Integration

You connect Replit to SpyFu by subscribing to an API-enabled SpyFu plan, obtaining your API key from account settings, and storing it in Replit Secrets. Your server-side Python or Node.js code sends requests to the SpyFu REST API with your API key as a query parameter, retrieving competitor domain data, keyword rankings, PPC spend estimates, and ad copy history. SpyFu API access is included with paid plans β€” there is no free API tier.

Prerequisites

  • A Replit account with a Python or Node.js project created
  • A SpyFu paid plan (Basic or higher) with API access enabled at https://www.spyfu.com
  • An API key from SpyFu account settings under API & Integrations
  • Basic understanding of SEO metrics (organic keywords, SERP ranking, PPC spend)
  • Familiarity with making HTTP GET requests in Python (requests library) or Node.js (axios)

Step-by-step guide

1

Get Your SpyFu API Key

Log into your SpyFu account at https://www.spyfu.com and navigate to Account Settings. Look for the API section or 'API Access' β€” the location varies slightly by plan. If you are on the Basic plan or higher with API access enabled, your API key is displayed in this section as a long alphanumeric string. SpyFu does not offer a free API tier. If you are on the free plan, you will need to upgrade to at least the Basic plan ($39/month as of 2026) to get API access. The API is included in paid plans without an additional fee, though rate limits apply β€” typically 500 requests per day on the Basic plan and higher limits on Team/Agency plans. SpyFu also supports Basic auth for API requests, where your username is your API key and the password is 'X' (a placeholder). This alternative authentication method works the same as the query parameter method. For this tutorial, we use the query parameter approach as it is simpler. The SpyFu API documentation is available at https://www.spyfu.com/api β€” review the available endpoints before building your integration. Key endpoints include /core/v2/domains/stats (domain overview), /core/v2/domains/organic_keywords (top organic keywords), and /core/v2/domains/ppc_keywords (PPC keywords).

Pro tip: SpyFu API access is included with paid plans β€” check your current plan level. If you need API access for evaluation, start a trial of the Basic plan.

Expected result: You have a SpyFu API key from your account settings page.

2

Store the API Key in Replit Secrets

Open your Replit project and click the lock icon πŸ”’ in the left sidebar. Add a new secret: - Key: SPYFU_API_KEY - Value: your SpyFu API key Click 'Add Secret' to save. Access the key in Python with os.environ['SPYFU_API_KEY'] and in Node.js with process.env.SPYFU_API_KEY. SpyFu API keys are tied to your account and its subscription. Exposing the key could allow others to consume your API quota or access competitive data billed to your account. Replit's encrypted Secrets pane keeps the key out of your source code and prevents it from being accidentally committed to GitHub.

Pro tip: If you are building a multi-client agency tool, all clients share your single SpyFu API key β€” plan your rate limit budget accordingly across all client queries.

Expected result: SPYFU_API_KEY appears in the Replit Secrets pane with its value hidden.

3

Query SpyFu Competitor Data with Python

Install requests with 'pip install requests flask'. The SpyFu API uses simple GET requests with query parameters including 'api_key', 'q' (the domain to analyze), 'pageSize', and 'startingRow' for pagination. The Flask server below provides three endpoints: /domain-stats for a domain overview (estimated monthly clicks, organic keywords count, PPC keywords count, monthly ad budget), /organic-keywords for the top ranking keywords, and /ppc-keywords for paid search keywords with estimated costs. Note that SpyFu data is estimated from their proprietary model β€” treat all numbers as approximations rather than exact figures. The data is most reliable for larger domains with significant traffic history in SpyFu's dataset.

app.py
1import os
2import requests
3from flask import Flask, request, jsonify
4
5app = Flask(__name__)
6
7SPYFU_API_KEY = os.environ["SPYFU_API_KEY"]
8BASE_URL = "https://www.spyfu.com/apis/core_api/v2"
9
10
11def spyfu_get(endpoint: str, params: dict) -> dict:
12 """Make a GET request to the SpyFu API."""
13 params["api_key"] = SPYFU_API_KEY
14 resp = requests.get(f"{BASE_URL}{endpoint}", params=params)
15 resp.raise_for_status()
16 return resp.json()
17
18
19@app.route("/domain-stats")
20def domain_stats():
21 """Get high-level SEO and PPC stats for a domain."""
22 domain = request.args.get("domain")
23 if not domain:
24 return jsonify({"error": "domain parameter required"}), 400
25 try:
26 data = spyfu_get("/domains/stats", {"q": domain})
27 return jsonify(data)
28 except requests.HTTPError as e:
29 return jsonify({"error": str(e)}), e.response.status_code if e.response else 500
30
31
32@app.route("/organic-keywords")
33def organic_keywords():
34 """Get top organic keywords for a domain."""
35 domain = request.args.get("domain")
36 page_size = int(request.args.get("page_size", 20))
37 starting_row = int(request.args.get("starting_row", 0))
38 if not domain:
39 return jsonify({"error": "domain parameter required"}), 400
40 try:
41 data = spyfu_get("/domains/organic_keywords", {
42 "q": domain,
43 "pageSize": min(page_size, 100),
44 "startingRow": starting_row,
45 "sortBy": "monthly_clicks",
46 "sortOrder": "descending"
47 })
48 return jsonify(data)
49 except requests.HTTPError as e:
50 return jsonify({"error": str(e)}), e.response.status_code if e.response else 500
51
52
53@app.route("/ppc-keywords")
54def ppc_keywords():
55 """Get PPC keywords and ad data for a domain."""
56 domain = request.args.get("domain")
57 page_size = int(request.args.get("page_size", 20))
58 starting_row = int(request.args.get("starting_row", 0))
59 if not domain:
60 return jsonify({"error": "domain parameter required"}), 400
61 try:
62 data = spyfu_get("/domains/ppc_keywords", {
63 "q": domain,
64 "pageSize": min(page_size, 100),
65 "startingRow": starting_row,
66 "sortBy": "monthly_clicks",
67 "sortOrder": "descending"
68 })
69 return jsonify(data)
70 except requests.HTTPError as e:
71 return jsonify({"error": str(e)}), e.response.status_code if e.response else 500
72
73
74@app.route("/competitor-report")
75def competitor_report():
76 """Generate a combined organic + PPC report for a domain."""
77 domain = request.args.get("domain")
78 if not domain:
79 return jsonify({"error": "domain parameter required"}), 400
80 try:
81 stats = spyfu_get("/domains/stats", {"q": domain})
82 organic = spyfu_get("/domains/organic_keywords", {
83 "q": domain, "pageSize": 10, "startingRow": 0,
84 "sortBy": "monthly_clicks", "sortOrder": "descending"
85 })
86 ppc = spyfu_get("/domains/ppc_keywords", {
87 "q": domain, "pageSize": 10, "startingRow": 0,
88 "sortBy": "monthly_clicks", "sortOrder": "descending"
89 })
90 return jsonify({
91 "domain": domain,
92 "stats": stats,
93 "top_organic_keywords": organic.get("results", []),
94 "top_ppc_keywords": ppc.get("results", [])
95 })
96 except requests.HTTPError as e:
97 return jsonify({"error": str(e)}), e.response.status_code if e.response else 500
98
99
100if __name__ == "__main__":
101 app.run(host="0.0.0.0", port=3000, debug=True)

Pro tip: Use the 'sortBy=monthly_clicks&sortOrder=descending' parameters to get the most impactful keywords first β€” these are the ones driving the most traffic for the competitor.

Expected result: GET /competitor-report?domain=example.com returns a JSON object with domain stats, top organic keywords, and top PPC keywords.

4

Build a Node.js SpyFu Integration

Install dependencies with 'npm install express axios'. The Node.js version uses axios for HTTP requests and provides the same endpoint structure as the Python version. The server below adds a /keyword-competitors endpoint that takes a keyword (rather than a domain) and returns the top domains ranking organically and running PPC ads for that keyword. This is useful for keyword-first competitor analysis: find who else is targeting a keyword you care about.

server.js
1const express = require('express');
2const axios = require('axios');
3
4const app = express();
5app.use(express.json());
6
7const SPYFU_API_KEY = process.env.SPYFU_API_KEY;
8const BASE_URL = 'https://www.spyfu.com/apis/core_api/v2';
9
10async function spyfuGet(endpoint, params = {}) {
11 const { data } = await axios.get(`${BASE_URL}${endpoint}`, {
12 params: { ...params, api_key: SPYFU_API_KEY }
13 });
14 return data;
15}
16
17// Domain overview stats
18app.get('/domain-stats', async (req, res) => {
19 const { domain } = req.query;
20 if (!domain) return res.status(400).json({ error: 'domain parameter required' });
21 try {
22 const data = await spyfuGet('/domains/stats', { q: domain });
23 res.json(data);
24 } catch (err) {
25 res.status(err.response?.status || 500).json({ error: err.response?.data || err.message });
26 }
27});
28
29// Top organic keywords
30app.get('/organic-keywords', async (req, res) => {
31 const { domain, page_size = 20, starting_row = 0 } = req.query;
32 if (!domain) return res.status(400).json({ error: 'domain parameter required' });
33 try {
34 const data = await spyfuGet('/domains/organic_keywords', {
35 q: domain,
36 pageSize: Math.min(Number(page_size), 100),
37 startingRow: Number(starting_row),
38 sortBy: 'monthly_clicks',
39 sortOrder: 'descending'
40 });
41 res.json(data);
42 } catch (err) {
43 res.status(err.response?.status || 500).json({ error: err.response?.data || err.message });
44 }
45});
46
47// PPC keywords
48app.get('/ppc-keywords', async (req, res) => {
49 const { domain, page_size = 20, starting_row = 0 } = req.query;
50 if (!domain) return res.status(400).json({ error: 'domain parameter required' });
51 try {
52 const data = await spyfuGet('/domains/ppc_keywords', {
53 q: domain,
54 pageSize: Math.min(Number(page_size), 100),
55 startingRow: Number(starting_row),
56 sortBy: 'monthly_clicks',
57 sortOrder: 'descending'
58 });
59 res.json(data);
60 } catch (err) {
61 res.status(err.response?.status || 500).json({ error: err.response?.data || err.message });
62 }
63});
64
65// Keyword-based competitor lookup
66app.get('/keyword-competitors', async (req, res) => {
67 const { keyword, page_size = 10 } = req.query;
68 if (!keyword) return res.status(400).json({ error: 'keyword parameter required' });
69 try {
70 const data = await spyfuGet('/keywords/organic_competitors', {
71 q: keyword,
72 pageSize: Math.min(Number(page_size), 50)
73 });
74 res.json(data);
75 } catch (err) {
76 res.status(err.response?.status || 500).json({ error: err.response?.data || err.message });
77 }
78});
79
80app.listen(3000, '0.0.0.0', () => {
81 console.log('SpyFu integration server running on port 3000');
82});

Pro tip: The /keyword-competitors endpoint is useful for keyword research β€” it shows which domains are already ranking for your target keyword, letting you gauge competition level before investing in SEO or PPC.

Expected result: GET /organic-keywords?domain=competitor.com returns a JSON object with the competitor's top organic keywords sorted by estimated monthly clicks.

5

Deploy and Schedule Competitor Monitoring

Click the Deploy button in Replit and choose Autoscale for an on-demand competitive intelligence API. If you want to schedule regular competitor checks (e.g., weekly reports), use a Scheduled deployment instead, which runs your script on a cron-like schedule without needing an external scheduler. For a scheduled monitoring script, create a main function that runs the competitor analysis for your tracked domains, formats the results, and sends the report by email or posts it to a Slack channel. The Replit Scheduled deployment type runs the script at your configured interval and stops it when done. After deploying, verify your API key is accessible in the production environment by checking that the first SpyFu request succeeds. Review SpyFu API rate limits in your account plan to ensure your scheduled queries stay within daily limits.

.replit
1[[ports]]
2internalPort = 3000
3externalPort = 80
4
5[deployment]
6run = ["node", "server.js"]
7deploymentTarget = "cloudrun"

Pro tip: SpyFu data updates weekly for most domains. Running more than one competitive analysis per day per domain is unlikely to show new data and wastes API quota.

Expected result: Your deployed Replit app serves SpyFu competitive intelligence queries at the production URL with the API key securely stored in Secrets.

Common use cases

Automated Competitor Keyword Report

A Replit backend queries SpyFu weekly for the top organic and PPC keywords of a list of competitor domains, compares the results to the previous week, and sends a summary email highlighting new keywords, dropped rankings, and PPC budget changes. This automates a manual competitor analysis process that would otherwise take hours.

Replit Prompt

Build a Python script that queries SpyFu for the top 50 organic keywords of three competitor domains, identifies keywords that overlap across all three, and outputs a CSV report sorted by estimated monthly clicks.

Copy this prompt to try it in Replit

PPC Gap Analysis Tool

A Replit API endpoint accepts a client's domain and their top competitor's domain, queries SpyFu for keywords each domain is bidding on, and returns a list of keywords the competitor bids on that the client does not. This PPC gap analysis helps agencies quickly identify paid search opportunities for their clients.

Replit Prompt

Create a Flask endpoint that accepts two domains, fetches their PPC keywords from SpyFu, and returns the keywords appearing in the competitor's paid campaigns but not in the client's, sorted by competitor estimated monthly ad clicks.

Copy this prompt to try it in Replit

Domain SEO Snapshot Dashboard

A Replit web app provides an internal dashboard where a marketing team can enter any competitor domain and instantly see key SpyFu metrics: estimated organic monthly clicks, number of ranking keywords, estimated PPC monthly spend, and top-performing ad copy examples. This replaces manual lookups in the SpyFu web UI.

Replit Prompt

Write an Express server with a /domain-report route that accepts a domain parameter, queries multiple SpyFu endpoints, and returns a consolidated JSON report with organic rank data and PPC metrics in a single response.

Copy this prompt to try it in Replit

Troubleshooting

HTTP 403 Forbidden when calling the SpyFu API

Cause: API access is not enabled on your current SpyFu plan, or the API key is incorrect or has been regenerated.

Solution: Log into SpyFu and verify your plan includes API access. Check the Account Settings > API section for the current API key β€” if the key was regenerated, update SPYFU_API_KEY in Replit Secrets. Free plan users must upgrade to Basic or higher.

Empty results array for a domain that clearly exists

Cause: SpyFu may not have sufficient data for the domain queried. Small or new domains with low traffic often appear in SpyFu but return empty keyword arrays because SpyFu has not accumulated enough data.

Solution: Try a well-known domain (e.g., 'amazon.com') to confirm the API is working. For small domains, SpyFu may return stats fields with zero values. Check the 'totalAvailableResults' field in the response β€” if it is zero, SpyFu has no data for that domain.

typescript
1# Check if data exists before processing
2if data.get('totalAvailableResults', 0) == 0:
3 return jsonify({'message': 'No SpyFu data available for this domain', 'results': []})

Rate limit errors after running many domain queries

Cause: SpyFu API rate limits vary by plan. Running bulk analysis across many domains in rapid succession can exhaust daily request quotas.

Solution: Add a short delay between API calls in batch processing scripts. Cache domain results for at least 24 hours since SpyFu data updates weekly. Check your SpyFu account for current API usage to see how much quota remains.

typescript
1import time
2
3domains = ['competitor1.com', 'competitor2.com', 'competitor3.com']
4for domain in domains:
5 data = spyfu_get('/domains/stats', {'q': domain})
6 # process data
7 time.sleep(1) # 1 second between requests

SPYFU_API_KEY is undefined or None in the running server

Cause: The Replit Secret was added after the server started running, or the variable name in Secrets does not exactly match what the code references.

Solution: Restart the Repl after adding a new secret. Check that the key name in Replit Secrets is exactly SPYFU_API_KEY (case-sensitive). Use os.environ.get('SPYFU_API_KEY', 'missing') to detect missing secrets early during startup.

typescript
1SPYFU_API_KEY = os.environ.get('SPYFU_API_KEY')
2if not SPYFU_API_KEY:
3 raise ValueError('SPYFU_API_KEY secret is missing. Add it in Replit Secrets.')

Best practices

  • Store SPYFU_API_KEY in Replit Secrets (lock icon πŸ”’) and never include it in client-side JavaScript or API responses.
  • Cache SpyFu domain results for at least 24 hours β€” data updates weekly, so repeated queries for the same domain within a day return identical results and waste API quota.
  • Always check totalAvailableResults before processing domain data β€” small or new domains may return zero results.
  • Use pageSize and startingRow parameters for pagination when analyzing large keyword datasets rather than requesting all data in a single call.
  • Treat all SpyFu traffic and spend estimates as approximations β€” they are modeled from SpyFu's proprietary data and should be used for directional analysis, not as exact figures.
  • Deploy on Autoscale for interactive competitor lookups or Scheduled deployment for automated weekly reports β€” avoid Reserved VM for this use case.
  • Track multiple competitors over time by storing results in a database rather than fetching fresh data every time β€” this enables trend analysis across weeks and months.
  • Include the domain's SpyFu page URL (https://www.spyfu.com/overview/domain?query={domain}) in your reports so stakeholders can click through to full SpyFu UI for deeper analysis.

Alternatives

Frequently asked questions

How do I get a SpyFu API key?

Log into your SpyFu account and navigate to Account Settings, then look for the API or Integrations section. Your API key is displayed there. SpyFu API access is included with paid plans (Basic and above) β€” free accounts do not have API access.

Is the SpyFu API available on the free plan?

No. SpyFu API access requires a paid subscription (Basic plan or higher). If you are on the free tier, you can only view data through the SpyFu web interface. Upgrade your plan in SpyFu account settings to unlock API access.

How accurate is SpyFu data for competitor analysis?

SpyFu data is estimated from their proprietary model that analyzes billions of search results over time. Traffic and spend figures are approximations that are typically accurate within an order of magnitude for larger domains. Small or new domains may have limited or missing data. Use SpyFu for directional competitive intelligence rather than precise measurement.

Can I use SpyFu to track multiple competitors automatically in Replit?

Yes. Build a Python or Node.js script that iterates over a list of competitor domains, queries SpyFu for each, and stores results in a database or exports to a spreadsheet. Schedule the script using Replit's Scheduled deployment type to run weekly. Cache results to avoid redundant API calls since SpyFu data updates at most weekly.

What is the difference between SpyFu and SEMrush for API access?

SpyFu specializes in competitor PPC and organic search intelligence with deep historical ad data, while SEMrush offers a broader API covering keyword research, site audit, social tracking, and more. SpyFu is better for teams focused specifically on competitor PPC analysis; SEMrush is better when you need a comprehensive digital marketing data API.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation β€” no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.