To integrate Replit with Ahrefs, store your Ahrefs API token in Replit Secrets (lock icon π in sidebar), then call the Ahrefs API v3 from your server-side Python or Node.js code to retrieve backlink data, keyword rankings, and domain metrics. Ahrefs does not offer a free API tier β a paid subscription with API access is required. All calls should be made server-side to protect your token.
Why Integrate Ahrefs with Replit?
Ahrefs has one of the largest backlink indexes in the industry, updated constantly from its own web crawler. By integrating the Ahrefs API into a Replit project, you can build automated SEO dashboards, competitor monitoring tools, backlink audit scripts, and keyword tracking systems that run on a schedule or respond to HTTP requests β without maintaining any local infrastructure.
The Ahrefs API v3 provides access to the same data that powers the Ahrefs web app: domain ratings, URL ratings, organic keyword counts, referring domain counts, backlink profiles, and SERP data. You can query individual URLs, entire domains, or subdomains. The API uses simple HTTPS GET requests with query parameters, making it easy to call from both Python and Node.js without SDK dependencies.
Common use cases for Replit and Ahrefs include: building a white-label SEO reporting tool that pulls metrics on demand, creating a scheduled script that monitors a client's domain rating and emails alerts when it changes, automating competitor backlink analysis as part of a content strategy workflow, or building an internal tool that lets your team query Ahrefs data without logging into the web app.
Integration method
The Replit-Ahrefs integration works by making authenticated HTTPS requests to the Ahrefs API v3 from your Replit server-side code. You store your Ahrefs API token in Replit Secrets and pass it as a Bearer token in each request header. All API calls must be made server-side β the Ahrefs API does not support direct browser calls, and exposing your token client-side would allow anyone to consume your paid API quota.
Prerequisites
- An Ahrefs account with an active subscription that includes API access (Standard plan or higher)
- An Ahrefs API token β generate it from app.ahrefs.com/user/api
- A Replit account with a Node.js or Python Repl
- Basic familiarity with making HTTP requests in your chosen language
Step-by-step guide
Get Your Ahrefs API Token
Get Your Ahrefs API Token
The Ahrefs API uses token-based authentication. To generate your API token, log into your Ahrefs account at app.ahrefs.com and navigate to Account β API. If you have an eligible subscription, you will see an 'API' section with your token. Click 'Generate' if no token exists yet. The Ahrefs API v3 uses Bearer token authentication β you include your token in an Authorization header with every request. The base URL for all v3 endpoints is https://api.ahrefs.com/v3/. Important: Ahrefs API access is included with Standard ($199/mo), Advanced ($399/mo), and Enterprise plans. The Lite plan does not include API access. Check your plan before proceeding. The API has rate limits that vary by plan: Standard gets 500 rows per request and up to several thousand credits per month. Each endpoint call consumes a certain number of 'row credits' based on how many rows of data you request. Monitor your usage in the API dashboard to avoid unexpected credit exhaustion. Keep your token private β anyone with your token can consume your API credits and access the data associated with your account.
Pro tip: Ahrefs API access is tied to your account subscription. If your team needs to share API access, generate separate tokens per developer where possible, or create a shared service account.
Expected result: You have an Ahrefs API token (a long alphanumeric string) visible in the API section of your Ahrefs account settings.
Store Your API Token in Replit Secrets
Store Your API Token in Replit Secrets
Never hardcode your Ahrefs API token in your source files. Replit provides a built-in Secrets manager that encrypts and injects your credentials at runtime. In your Replit project, click the lock icon (π) in the left sidebar to open the Secrets panel. Click 'New Secret' and add: Key: AHREFS_API_TOKEN Value: your Ahrefs API token Click 'Add Secret'. The value is now encrypted and stored separately from your code. It will never appear in your Git history or in the Replit file browser. Replit's Secret Scanner also automatically blocks any accidental commits that contain patterns matching common API key formats β an extra safety net. Access the token in your code: - Node.js: const token = process.env.AHREFS_API_TOKEN; - Python: import os; token = os.environ['AHREFS_API_TOKEN'] If you restart your Repl and the variable does not load, open the Secrets panel and verify the key name is spelled exactly as you reference it in code (case-sensitive).
Pro tip: After adding the secret, test that it loaded by logging its length: console.log('Token length:', process.env.AHREFS_API_TOKEN?.length). This confirms the secret is accessible without printing the actual token value.
Expected result: AHREFS_API_TOKEN appears in the Replit Secrets panel and is accessible via process.env.AHREFS_API_TOKEN in Node.js or os.environ['AHREFS_API_TOKEN'] in Python.
Query the Ahrefs API from Node.js
Query the Ahrefs API from Node.js
The Ahrefs API v3 uses simple GET requests with query parameters. The most commonly used endpoints are /site-explorer/overview (domain-level metrics), /site-explorer/backlinks (backlink list), and /site-explorer/organic-keywords (keyword rankings). Each request requires a target parameter (the domain or URL to analyze), a select parameter (comma-separated list of fields you want), and optionally limit, offset, and order_by parameters for pagination. The code below demonstrates fetching domain-level overview metrics β domain rating, organic keywords, and organic traffic estimate β using Node's built-in fetch (available in Node 18+, which is Replit's default). Install nothing β the built-in fetch handles HTTPS requests without any packages.
1// ahrefs-client.js β Ahrefs API v3 client2const AHREFS_API_BASE = 'https://api.ahrefs.com/v3';34function getToken() {5 const token = process.env.AHREFS_API_TOKEN;6 if (!token) throw new Error('AHREFS_API_TOKEN secret is not set');7 return token;8}910function buildHeaders() {11 return {12 'Authorization': `Bearer ${getToken()}`,13 'Accept': 'application/json'14 };15}1617// Fetch domain overview: DR, organic keywords, organic traffic18async function getDomainOverview(domain) {19 const params = new URLSearchParams({20 target: domain,21 output: 'json',22 select: 'domain_rating,org_keywords,org_traffic'23 });24 const url = `${AHREFS_API_BASE}/site-explorer/metrics?${params}`;25 const res = await fetch(url, { headers: buildHeaders() });26 if (!res.ok) {27 const err = await res.text();28 throw new Error(`Ahrefs API error ${res.status}: ${err}`);29 }30 return res.json();31}3233// Fetch top referring domains for a target34async function getReferringDomains(domain, limit = 10) {35 const params = new URLSearchParams({36 target: domain,37 output: 'json',38 limit: limit,39 select: 'domain,domain_rating,linked_domains,dofollow_linked_domains'40 });41 const url = `${AHREFS_API_BASE}/site-explorer/refdomains?${params}`;42 const res = await fetch(url, { headers: buildHeaders() });43 if (!res.ok) {44 const err = await res.text();45 throw new Error(`Ahrefs API error ${res.status}: ${err}`);46 }47 return res.json();48}4950// Fetch top organic keywords for a domain51async function getOrganicKeywords(domain, limit = 20) {52 const params = new URLSearchParams({53 target: domain,54 output: 'json',55 limit: limit,56 select: 'keyword,volume,position,traffic'57 });58 const url = `${AHREFS_API_BASE}/site-explorer/organic-keywords?${params}`;59 const res = await fetch(url, { headers: buildHeaders() });60 if (!res.ok) {61 const err = await res.text();62 throw new Error(`Ahrefs API error ${res.status}: ${err}`);63 }64 return res.json();65}6667module.exports = { getDomainOverview, getReferringDomains, getOrganicKeywords };Pro tip: The Ahrefs API charges credits per row of data returned. Use the select parameter to request only the fields you actually need β this reduces both credit usage and response payload size.
Expected result: getDomainOverview('example.com') returns an object with domain_rating, org_keywords, and org_traffic fields.
Build an SEO Metrics API Server with Express
Build an SEO Metrics API Server with Express
Wrap the Ahrefs client in an Express server to create a reusable SEO data endpoint. This allows other apps, dashboards, or team members to query SEO metrics for any domain via a simple HTTP request without needing access to your Ahrefs credentials. Install Express: In the Replit Shell, run npm install express. Deploy this as an Autoscale deployment on Replit β SEO reporting is a lightweight, on-demand workload that benefits from Autoscale's pay-per-request pricing rather than a Reserved VM running 24/7.
1// server.js β Express SEO metrics server using Ahrefs API2const express = require('express');3const { getDomainOverview, getReferringDomains, getOrganicKeywords } = require('./ahrefs-client');45const app = express();6app.use(express.json());78// GET /metrics?domain=example.com9app.get('/metrics', async (req, res) => {10 const { domain } = req.query;11 if (!domain) {12 return res.status(400).json({ error: 'domain query parameter is required' });13 }14 try {15 const overview = await getDomainOverview(domain);16 res.json({ domain, metrics: overview });17 } catch (err) {18 console.error('Ahrefs error:', err.message);19 res.status(500).json({ error: err.message });20 }21});2223// GET /backlinks?domain=example.com&limit=2024app.get('/backlinks', async (req, res) => {25 const { domain, limit = 10 } = req.query;26 if (!domain) {27 return res.status(400).json({ error: 'domain query parameter is required' });28 }29 try {30 const data = await getReferringDomains(domain, parseInt(limit));31 res.json({ domain, referring_domains: data });32 } catch (err) {33 console.error('Ahrefs error:', err.message);34 res.status(500).json({ error: err.message });35 }36});3738// GET /keywords?domain=example.com&limit=2039app.get('/keywords', async (req, res) => {40 const { domain, limit = 20 } = req.query;41 if (!domain) {42 return res.status(400).json({ error: 'domain query parameter is required' });43 }44 try {45 const data = await getOrganicKeywords(domain, parseInt(limit));46 res.json({ domain, keywords: data });47 } catch (err) {48 console.error('Ahrefs error:', err.message);49 res.status(500).json({ error: err.message });50 }51});5253const PORT = process.env.PORT || 3000;54app.listen(PORT, '0.0.0.0', () => {55 console.log(`Ahrefs SEO server running on port ${PORT}`);56});Pro tip: Add a simple API key check to your Express server (compare a request header against an environment variable) to prevent unauthorized use of your SEO endpoint before deploying it publicly.
Expected result: GET /metrics?domain=example.com returns JSON with the domain's Ahrefs metrics. The server runs on port 3000 and responds to requests.
Python Implementation Using Requests
Python Implementation Using Requests
If your Replit project uses Python, the requests library makes Ahrefs API calls straightforward. Flask provides a lightweight server layer for exposing the data as an API endpoint. Install dependencies in the Replit Shell: pip install requests flask The Python implementation below mirrors the Node.js version but uses Python conventions. The requests library handles the HTTPS connection and JSON parsing cleanly. Flask runs with host='0.0.0.0' to accept external connections, which is required for Replit's deployment system to route traffic to your app.
1# app.py β Flask SEO server using Ahrefs API2import os3import requests4from flask import Flask, request, jsonify56app = Flask(__name__)78AHREFS_API_BASE = 'https://api.ahrefs.com/v3'910def get_headers():11 token = os.environ.get('AHREFS_API_TOKEN')12 if not token:13 raise ValueError('AHREFS_API_TOKEN environment variable is not set')14 return {15 'Authorization': f'Bearer {token}',16 'Accept': 'application/json'17 }1819def fetch_domain_overview(domain):20 params = {21 'target': domain,22 'output': 'json',23 'select': 'domain_rating,org_keywords,org_traffic'24 }25 resp = requests.get(26 f'{AHREFS_API_BASE}/site-explorer/metrics',27 headers=get_headers(),28 params=params,29 timeout=1530 )31 resp.raise_for_status()32 return resp.json()3334def fetch_organic_keywords(domain, limit=20):35 params = {36 'target': domain,37 'output': 'json',38 'limit': limit,39 'select': 'keyword,volume,position,traffic'40 }41 resp = requests.get(42 f'{AHREFS_API_BASE}/site-explorer/organic-keywords',43 headers=get_headers(),44 params=params,45 timeout=1546 )47 resp.raise_for_status()48 return resp.json()4950@app.route('/metrics')51def metrics():52 domain = request.args.get('domain')53 if not domain:54 return jsonify({'error': 'domain parameter required'}), 40055 try:56 data = fetch_domain_overview(domain)57 return jsonify({'domain': domain, 'metrics': data})58 except requests.HTTPError as e:59 return jsonify({'error': str(e)}), 5006061@app.route('/keywords')62def keywords():63 domain = request.args.get('domain')64 limit = int(request.args.get('limit', 20))65 if not domain:66 return jsonify({'error': 'domain parameter required'}), 40067 try:68 data = fetch_organic_keywords(domain, limit)69 return jsonify({'domain': domain, 'keywords': data})70 except requests.HTTPError as e:71 return jsonify({'error': str(e)}), 5007273if __name__ == '__main__':74 app.run(host='0.0.0.0', port=3000)Pro tip: Use a timeout parameter on all requests calls (timeout=15) to prevent your server from hanging if the Ahrefs API is slow to respond. Ahrefs is generally fast, but large queries on high-traffic domains may take a few seconds.
Expected result: Running python app.py starts a Flask server. GET /metrics?domain=example.com returns Ahrefs domain metrics as JSON.
Common use cases
Automated Domain Authority Dashboard
Build a Replit web server that accepts a domain name and returns its Ahrefs domain rating, organic traffic estimate, and referring domain count in a single API call. This makes it easy to build client-facing SEO reports or internal monitoring dashboards.
Build a Node.js Express server with a GET /seo-metrics?domain=example.com endpoint. Use the Ahrefs API to fetch the domain rating, organic keywords count, and estimated organic traffic for the given domain. Store AHREFS_API_TOKEN in environment variables and return the data as JSON.
Copy this prompt to try it in Replit
Backlink Monitor with Alerts
Create a scheduled Replit script that checks your domain's backlink count daily and compares it to the previous reading. If the count drops by more than a threshold, it triggers an alert via email or Slack webhook. Useful for catching negative SEO attacks early.
Write a Python script that queries the Ahrefs API for the total backlink count for a target domain, compares it to a stored count in a JSON file, and prints a warning if the count dropped by more than 5%. Schedule it to run daily. Read AHREFS_API_TOKEN from os.environ.
Copy this prompt to try it in Replit
Competitor Keyword Gap Analysis
Build a script that retrieves the top organic keywords for two competing domains using the Ahrefs API, then identifies keywords the competitor ranks for that your domain does not. Output a CSV file with the gap keywords, their search volume, and the competitor's ranking position.
Create a Python script that fetches the top 100 organic keywords for two domains using the Ahrefs API, finds keywords in domain B that are not in domain A's top 100, and writes the results to a CSV file called keyword-gaps.csv. Store AHREFS_API_TOKEN as an environment variable.
Copy this prompt to try it in Replit
Troubleshooting
HTTP 401 Unauthorized β 'Invalid token' or 'Authentication failed'
Cause: The API token is missing, malformed, or the Authorization header is not formatted correctly as 'Bearer {token}'.
Solution: Open Replit Secrets and verify AHREFS_API_TOKEN is set and contains no extra spaces or line breaks. Check that your code reads process.env.AHREFS_API_TOKEN (Node.js) or os.environ['AHREFS_API_TOKEN'] (Python). Confirm the header is exactly 'Authorization: Bearer your-token-here'.
1// Debug: print header without revealing full token2const token = process.env.AHREFS_API_TOKEN || '';3console.log('Token set:', token.length > 0, 'First 8 chars:', token.slice(0, 8));HTTP 403 Forbidden β 'Your account does not have access to this endpoint'
Cause: Your Ahrefs subscription plan does not include API access. Only Standard, Advanced, and Enterprise plans include API access β the Lite plan does not.
Solution: Log into app.ahrefs.com, go to Account β API, and verify your plan includes API access. If you are on the Lite plan, you would need to upgrade to access the API.
HTTP 429 Too Many Requests β API rate limit exceeded
Cause: You have exceeded the number of requests or row credits allowed by your Ahrefs plan in the current billing period.
Solution: Add retry logic with exponential backoff for 429 responses, and cache API results in memory or a file to avoid redundant calls. Check your API usage dashboard in Ahrefs to see remaining credits.
1async function fetchWithRetry(url, headers, maxRetries = 3) {2 for (let i = 0; i < maxRetries; i++) {3 const res = await fetch(url, { headers });4 if (res.status === 429) {5 const wait = Math.pow(2, i) * 2000;6 console.log(`Rate limited. Retrying in ${wait}ms...`);7 await new Promise(r => setTimeout(r, wait));8 continue;9 }10 return res;11 }12 throw new Error('Max retries exceeded');13}Empty results array even though the domain has data in the Ahrefs web app
Cause: The select parameter may reference field names that do not exist for the requested endpoint, or the target parameter format is wrong (e.g., including 'https://' when only the domain is expected).
Solution: Use just the bare domain name (e.g., 'example.com' not 'https://www.example.com') as the target parameter. Check the Ahrefs API v3 documentation for the exact field names supported by each endpoint.
1// Strip protocol and trailing slashes from domain input2function cleanDomain(input) {3 return input.replace(/^https?:\/\//, '').replace(/\/+$/, '').split('/')[0];4}Best practices
- Store AHREFS_API_TOKEN exclusively in Replit Secrets β never in .env files, source code, or configuration files that could be committed to Git
- Cache Ahrefs API results for at least an hour using an in-memory store or JSON file, since SEO metrics change slowly and repeated calls waste credits
- Use the select parameter to request only the fields your application needs β each row returned costs credits, and fewer fields means smaller payloads
- Add input validation to strip 'https://', 'www.', and trailing slashes from domain inputs before passing them to the API
- Log API errors with enough context to debug (status code, endpoint called) but never log the full token value
- Implement exponential backoff for 429 responses to handle temporary rate limit spikes gracefully
- Deploy SEO reporting tools as Autoscale deployments on Replit β they receive infrequent traffic and do not need a persistent Reserved VM
- Monitor your Ahrefs API credit consumption in the account dashboard and set up alerts if you have a budget-sensitive integration
Alternatives
SEMrush offers a broader digital marketing API covering PPC, social, and content in addition to SEO, making it better if you need a single API for multiple marketing data types.
Moz's Links API provides domain authority and page authority metrics at a lower price point, making it a good alternative if your primary need is DA/PA data rather than full backlink analysis.
Serpstat offers competitive SEO API pricing with keyword and backlink data, making it worth considering if Ahrefs API credits are cost-prohibitive for your use case.
Frequently asked questions
Does Replit work with the Ahrefs API?
Yes. Ahrefs API v3 accepts standard HTTPS GET requests, which work from any Replit server-side code in Node.js or Python. Store your API token in Replit Secrets and call the API from your backend β do not call it from client-side JavaScript in the browser.
How do I store my Ahrefs API token in Replit?
Click the lock icon (π) in the Replit sidebar to open the Secrets panel. Add a new secret with key AHREFS_API_TOKEN and your token as the value. Access it in Node.js as process.env.AHREFS_API_TOKEN or in Python as os.environ['AHREFS_API_TOKEN']. The value is encrypted and never visible in your code files.
Can I use the Ahrefs API for free on Replit?
No. Ahrefs API access requires a Standard plan ($199/mo) or higher. The Lite plan does not include API access. Once you have an eligible subscription, there are no additional API charges beyond your plan's included row credits.
How many API requests can I make from Replit?
Ahrefs measures API usage in 'row credits' rather than request count. The Standard plan includes a certain number of row credits per month β each row of data returned (e.g., one keyword or one backlink) consumes one credit. Use the select parameter to limit fields and the limit parameter to control row count per request.
Why is the Ahrefs API returning 403 on my Replit app?
A 403 response typically means your Ahrefs subscription plan does not include API access. Log into app.ahrefs.com β Account β API to verify your plan. If you see the API section, your plan supports it. A 403 can also occur if you are trying to access an endpoint not included in your plan tier.
Should I use Autoscale or Reserved VM for my Ahrefs-powered Replit app?
Autoscale is the right choice for most Ahrefs integrations. SEO reporting tools are typically called on demand (a user requests a report) rather than continuously. Autoscale scales to zero when idle, so you only pay when the app is actually serving requests.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation