# How to Integrate Retool with Serpstat

- Tool: Retool
- Difficulty: Intermediate
- Time required: 25 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Serpstat by creating a REST API Resource with Serpstat's API base URL and token authentication. Use Serpstat's API to build SERP rank tracking dashboards that monitor keyword positions, track competitor rankings, view backlink data, and alert on significant position changes — giving your SEO team a configurable monitoring panel as a budget-friendly alternative to enterprise SEO platforms.

## Build a Serpstat SERP Rank Tracking Dashboard in Retool

Serpstat positions itself as a comprehensive yet affordable SEO platform, making it particularly popular with small agencies and in-house SEO teams that need keyword tracking, competitor analysis, and backlink data without the enterprise pricing of SEMrush or Ahrefs. Its API provides access to the same data available in the Serpstat web interface — keyword rankings, SERP feature presence, backlink profiles, and competitor overlap analysis.

Retool enables you to build a custom rank tracking dashboard that pulls Serpstat data on a schedule, stores position history in a database, and surfaces meaningful alerts when keywords move significantly in the SERPs. Unlike Serpstat's built-in interface, a Retool dashboard can combine Serpstat keyword data with your own website analytics (via Google Analytics or a database resource), creating a complete picture that connects ranking changes to traffic and conversion outcomes.

Serpstat's API uses token-based authentication with the token passed as a query parameter. Retool's server-side proxy ensures this token is never exposed to end users. The API follows a consistent pattern across all report types, and Serpstat returns clean JSON responses that are straightforward to work with in JavaScript transformers. Note that API access requires a Serpstat plan with API units included.

## Before you start

- A Serpstat account with a paid plan that includes API access (check your plan's included API units)
- A Serpstat API token (Serpstat Settings → API → Your API token)
- A Retool account with permission to create Resources
- Optional: a PostgreSQL or Retool Database for storing daily rank snapshots and history
- Familiarity with Retool's query editor, Table component, and basic Chart configuration

## Step-by-step guide

### 1. Create a Serpstat REST API Resource

Navigate to the Resources tab in your Retool instance and click Add Resource. Select REST API from the list of resource types. Name the resource 'Serpstat API'.

In the Base URL field, enter https://api.serpstat.com/v4. This is the current Serpstat REST API v4 base URL. All endpoint paths will be appended to this base URL.

Serpstat authenticates API requests using an API token passed as a URL query parameter named token. Rather than adding it to every individual query, configure it as a default URL parameter at the resource level. In the URL Parameters section, click Add Parameter. Set the parameter name to token and the value to your Serpstat API token, which you can find in Serpstat's account settings under Settings → API.

For better security, store the token as a configuration variable in Retool. Go to Settings → Configuration Variables, create a variable named SERPSTAT_API_TOKEN, mark it as Secret, and paste your token. Then in the resource's URL parameter value field, use {{ retoolContext.configVars.SERPSTAT_API_TOKEN }} instead of the raw token.

Serpstat's API returns JSON responses. Add a default header: Accept with value application/json to ensure consistent JSON formatting in responses. Leave all other settings at defaults and click Save Changes.

**Expected result:** The Serpstat API resource is saved in Retool with the base URL and token URL parameter configured. The resource is available for queries across all apps in your workspace.

### 2. Query domain keyword rankings and position data

Create your first Serpstat query to retrieve keyword rankings for a domain. In your Retool app, open the Code panel and click + to add a query. Name it getDomainKeywords and select the Serpstat API resource.

Set Method to GET. In the Path field, enter /domain-keywords. Add the following URL parameters:
- domain: {{ textInput_domain.value }} (the domain to analyze, without protocol, e.g., example.com)
- se: g_us (search engine and country — g_us for Google US, g_uk for Google UK, etc.)
- page: 1
- size: 100 (number of keywords per page, maximum typically 1000)
- sort: traff (sort by traffic estimate, descending)

Serpstat returns JSON with a data object containing a result array. Each result item includes: keyword, position (current ranking position), cost (CPC estimate), concurrency (competition score), traff (estimated traffic), features (SERP features present), url (the ranking URL), and previous_pos (previous position for comparison).

Add a JavaScript transformer to format the response:

Bind the transformed results to a Table component. Add a Text Input component for domain entry. Connect its onChange event to trigger getDomainKeywords so the table updates when the domain input changes.

For the summary statistics view, create a query named getDomainSummary:
- Path: /domain-summary
- URL parameters: domain = {{ textInput_domain.value }}, se = g_us

This returns aggregate metrics: total keyword count, estimated monthly traffic, visibility score, and ad keywords count. Display these in Stat components above the keyword table.

```
// JavaScript transformer — format Serpstat keyword rankings for display
const keywords = (data.data?.result || []);

return keywords.map(kw => {
  const current = parseInt(kw.position) || 0;
  const previous = parseInt(kw.previous_pos) || current;
  const change = previous - current; // positive = moved up (improved)

  return {
    keyword: kw.keyword || 'N/A',
    position: current || 'Not ranked',
    previous_position: previous || 'N/A',
    position_change: change !== 0
      ? (change > 0 ? `▲ ${change}` : `▼ ${Math.abs(change)}`)
      : '—',
    change_direction: change > 0 ? 'improved'
      : change < 0 ? 'declined' : 'stable',
    search_volume: parseInt(kw.concurrency || 0) || 0,
    traffic_estimate: parseInt(kw.traff || 0) || 0,
    cpc: kw.cost ? `$${parseFloat(kw.cost).toFixed(2)}` : 'N/A',
    ranking_url: kw.url || 'N/A',
    serp_features: (kw.features || []).join(', ') || 'None',
    has_featured_snippet: (kw.features || []).includes('featured_snippet')
  };
}).sort((a, b) => b.traffic_estimate - a.traffic_estimate);
```

**Expected result:** The keyword rankings table populates with up to 100 top keywords for the entered domain, showing current and previous positions with color-coded change indicators. Stat components show the domain's aggregate traffic estimate and total keyword count.

### 3. Fetch SERP analysis and competitor data

Create queries to analyze SERP competition for specific keywords and compare your domain against competitors. Create a query named getSerpCompetitors:
- Path: /serp-competitors
- URL parameters:
  - keyword: {{ textInput_keyword.value }}
  - se: g_us
  - size: 10

This returns the top 10 ranking domains for the specified keyword with their position, domain, title, description, and SERP features they occupy.

Create a second query named getDomainCompetitors:
- Path: /domain-competitors
- URL parameters:
  - domain: {{ textInput_domain.value }}
  - se: g_us
  - page: 1
  - size: 20

This returns the domains with the most keyword overlap with your domain — your true organic competitors in the SERPs. Each result includes the competitor domain, overlap count (keywords where both domains appear), and the competitor's estimated traffic.

Bind getDomainCompetitors to a Table named table_competitors. When a competitor row is selected, trigger getDomainKeywords for the competitor domain to compare their ranking keyword set with yours. Add a Chart component showing the traffic overlap between your domain and the selected competitor.

For keyword gap analysis, create getKeywordGap:
- Path: /domain-keywords
- URL parameters for the competitor domain, then use a JavaScript query to find keywords in competitor results not present in your domain results

Display the gap keywords sorted by traffic estimate — these are your highest-priority content opportunities.

```
// JavaScript query — find keyword gap between your domain and competitor
const yourKeywords = new Set(
  (getDomainKeywords.data?.map(k => k.keyword) || [])
);

const competitorKeywords = (getCompetitorKeywords.data?.data?.result || []);

const gapKeywords = competitorKeywords
  .filter(kw => !yourKeywords.has(kw.keyword))
  .filter(kw => parseInt(kw.position) <= 10) // competitor ranks in top 10
  .map(kw => ({
    keyword: kw.keyword || 'N/A',
    competitor_position: parseInt(kw.position) || 0,
    your_position: 'Not ranking',
    traffic_estimate: parseInt(kw.traff || 0),
    cpc: kw.cost ? `$${parseFloat(kw.cost).toFixed(2)}` : 'N/A',
    opportunity_score: parseInt(kw.traff || 0) + (11 - parseInt(kw.position || 11))
  }))
  .sort((a, b) => b.opportunity_score - a.opportunity_score);

return {
  total_gap_keywords: gapKeywords.length,
  top_opportunities: gapKeywords.slice(0, 50)
};
```

**Expected result:** The competitor analysis table shows the top 10 organic competitors with keyword overlap counts. The keyword gap analysis returns competitor keywords where your domain doesn't rank in the top 20, sorted by opportunity score.

### 4. Set up daily rank tracking with position history storage

The most valuable use of the Serpstat API in Retool is building a historical rank tracker that stores daily position data and shows trends over time. This requires a database table for storing snapshots and a Retool Workflow to automate daily imports.

First, create a table in your connected database (PostgreSQL or Retool Database). The schema needs: id, domain, keyword, position, previous_position, traffic_estimate, serp_features, ranking_url, recorded_date.

In Retool, create a Workflow with a Schedule trigger set to run daily at 7 AM. Add a Resource Query block connected to the Serpstat API resource (getDomainKeywords query). Add a second Resource Query block connected to your database with an INSERT statement that writes each keyword's position data with the current date.

In your dashboard Retool app, create a getPositionHistory query:
- SQL: SELECT keyword, position, recorded_date FROM rank_tracking WHERE domain = '{{ textInput_domain.value }}' AND keyword = '{{ table_keywords.selectedRow.keyword }}' AND recorded_date >= CURRENT_DATE - INTERVAL '30 days' ORDER BY recorded_date ASC

Bind this to a Line Chart component with recorded_date on the x-axis and position on the y-axis (note: lower position = better ranking, so invert the axis). When a keyword row is selected in the main table, getPositionHistory runs automatically to show the 30-day trend.

Add a separate alert view — a Table showing all keywords where position changed by 5 or more places since last week — that loads on page open as the daily SEO briefing. For complex multi-domain rank tracking pipelines with automated client reporting, RapidDev's team can help architect a scalable SEO monitoring infrastructure.

```
-- SQL: create rank tracking table
CREATE TABLE IF NOT EXISTS rank_tracking (
  id SERIAL PRIMARY KEY,
  domain TEXT NOT NULL,
  keyword TEXT NOT NULL,
  position INTEGER,
  previous_position INTEGER,
  traffic_estimate INTEGER,
  serp_features TEXT,
  ranking_url TEXT,
  recorded_date DATE NOT NULL DEFAULT CURRENT_DATE
);
CREATE INDEX idx_rank_domain_date ON rank_tracking(domain, recorded_date);
CREATE INDEX idx_rank_keyword ON rank_tracking(keyword);

-- SQL: query position history for trend chart
SELECT
  keyword,
  position,
  traffic_estimate,
  recorded_date,
  LAG(position) OVER (PARTITION BY keyword ORDER BY recorded_date) AS prev_day_position,
  position - LAG(position) OVER (PARTITION BY keyword ORDER BY recorded_date) AS daily_change
FROM rank_tracking
WHERE
  domain = {{ textInput_domain.value }}
  AND keyword = {{ table_keywords.selectedRow.keyword }}
  AND recorded_date >= CURRENT_DATE - INTERVAL '30 days'
ORDER BY recorded_date ASC;
```

**Expected result:** The Retool Workflow stores daily position snapshots for tracked keywords. The rank history chart shows a 30-day position trend when a keyword is selected. The alerts table surfaces keywords with the largest position drops for immediate SEO team attention.

### 5. Build a position change alert panel

Create a position change monitoring view that gives the SEO team an at-a-glance briefing on keyword movements every morning. This view reads from your stored rank history database rather than calling the Serpstat API directly.

Create a query named getPositionChanges:
- SQL: SELECT keyword, current.position AS current_pos, previous.position AS prev_pos, (previous.position - current.position) AS position_change, current.traffic_estimate, current.ranking_url FROM rank_tracking current JOIN rank_tracking previous ON current.domain = previous.domain AND current.keyword = previous.keyword AND previous.recorded_date = CURRENT_DATE - 7 WHERE current.domain = '{{ textInput_domain.value }}' AND current.recorded_date = CURRENT_DATE AND ABS(previous.position - current.position) >= 5 ORDER BY ABS(previous.position - current.position) DESC

This query finds all keywords where position changed by 5 or more places in the last 7 days, sorted by the magnitude of change.

In your Retool app, split the position changes table into three views using Tab components or filtered Tables:
1. Biggest Gainers — keywords that moved up 5+ positions (position_change > 0)
2. Biggest Losers — keywords that dropped 5+ positions (position_change < 0)
3. New Rankings — keywords that weren't ranked previously but now appear in the top 50

Add Stat components showing aggregate counts: number of keywords improved this week, number declined, number stable. Apply red/green conditional formatting to the position change column.

For automated alerts, add a Retool Workflow that runs daily after the ranking import and checks if any tracked keywords dropped more than 10 positions. If found, send a Slack notification or email to the SEO team lead using a connected Slack or SendGrid resource in the same Workflow.

```
-- SQL: get significant position changes in the last 7 days
SELECT
  curr.keyword,
  curr.position AS current_position,
  prev.position AS previous_position,
  (prev.position - curr.position) AS position_change,
  curr.traffic_estimate,
  curr.ranking_url,
  CASE
    WHEN (prev.position - curr.position) > 0 THEN 'IMPROVED'
    WHEN (prev.position - curr.position) < 0 THEN 'DECLINED'
    ELSE 'STABLE'
  END AS change_type,
  ABS(prev.position - curr.position) AS change_magnitude
FROM rank_tracking curr
JOIN rank_tracking prev
  ON curr.domain = prev.domain
  AND curr.keyword = prev.keyword
  AND prev.recorded_date = CURRENT_DATE - INTERVAL '7 days'
WHERE
  curr.domain = {{ textInput_domain.value }}
  AND curr.recorded_date = CURRENT_DATE
  AND ABS(prev.position - curr.position) >= 3
ORDER BY change_magnitude DESC, curr.traffic_estimate DESC
LIMIT 100;
```

**Expected result:** The position change alert table surfaces the week's biggest keyword movements, split into gainers and losers with appropriate color coding. The Stat components show aggregate movement counts so the SEO team can assess the week at a glance.

## Best practices

- Store your Serpstat API token as a Secret configuration variable in Retool — never paste it directly into URL parameters where it could appear in browser network logs.
- Store daily rank snapshots in a database table instead of querying Serpstat's API on every dashboard load — this preserves API units and enables historical trend analysis.
- Set a reasonable page size (size=100 or less) for keyword queries to control API unit consumption — fetching 1,000 keywords on every dashboard view is expensive in both API units and load time.
- Use Retool Workflows on a daily schedule for rank tracking imports rather than ad-hoc API calls from the dashboard, so API units are spent efficiently on one batch import per day.
- Invert the y-axis on position history charts so that improving rankings (position 1 = best) appear as upward-trending lines, matching users' intuitive understanding of 'higher = better'.
- Combine Serpstat ranking data with Google Analytics or Google Search Console data in the same Retool app to correlate position changes with actual traffic impact — this helps prioritize which ranking drops need urgent attention.
- Set up automated Slack or email alerts in Retool Workflows when any tracked keyword drops more than 10 positions overnight, enabling the SEO team to investigate potential penalties or algorithm updates immediately.

## Use cases

### Build a keyword rank tracking dashboard with position history

Create a Retool dashboard that queries Serpstat for your domain's keyword rankings daily using a Retool Workflow, stores position data in a database table, and displays a 30-day position trend for any selected keyword. Highlight keywords that have moved significantly (5+ positions) in either direction this week so the SEO team can investigate causes and respond quickly.

Prompt example:

```
Build a rank tracking dashboard with a keyword search input, a Table showing current position, previous week's position, and position change for matching keywords, a line chart showing position history over the past 30 days for a selected keyword, and a red-highlighted section for keywords that dropped more than 5 places in the last 7 days.
```

### Competitor keyword gap analysis panel

Build a Retool panel that uses Serpstat's competitor API to identify keywords where your competitors rank in the top 10 but your domain does not appear on the first page. Display these gap keywords sorted by search volume and competitive difficulty, enabling the SEO team to prioritize content creation around high-opportunity terms.

Prompt example:

```
Create a keyword gap panel that queries Serpstat for keywords where a competitor domain ranks in positions 1-10 but your domain is not in the top 20, displays them sorted by search volume with keyword difficulty scores, and includes a filter to show only keywords with volume above 500 and difficulty below 60.
```

### SERP feature presence and rich snippet tracker

Build a monitoring dashboard that tracks which of your target keywords trigger SERP features (featured snippets, people-also-ask boxes, local packs, image carousels) and whether your domain is capturing those features. Alert the team when you gain or lose featured snippet positions, as these can dramatically affect click-through rates even for high-ranking pages.

Prompt example:

```
Build a SERP features dashboard that queries keywords with their SERP feature types from Serpstat, shows a breakdown of feature types present (featured snippet, video, images, local), highlights keywords where you rank top 3 but don't own the featured snippet, and tracks snippet ownership changes week over week.
```

## Troubleshooting

### API returns 401 Unauthorized or invalid token error

Cause: The API token URL parameter is missing, incorrectly named, or the token has expired or been regenerated in Serpstat's account settings.

Solution: Verify the URL parameter name is exactly 'token' (lowercase). Go to Serpstat's Settings → API to confirm your API token is current and copy it again. If using a configuration variable, verify the variable name matches exactly. Test by temporarily pasting the raw token value directly into the URL parameter to isolate configuration variable issues.

### Domain keywords query returns empty results for a domain that ranks for many keywords

Cause: The 'se' (search engine) parameter may be set to a database where Serpstat has limited data, or the domain format may include protocol or trailing slashes that the API doesn't accept.

Solution: Verify the domain parameter is a bare domain without protocol (use 'example.com' not 'https://example.com'). Try different 'se' values — g_us for Google US, g_uk for Google UK. Serpstat's database coverage varies by region and language. Check that Serpstat has data for this domain by searching it directly in Serpstat's web interface first.

### API unit quota is depleted faster than expected

Cause: Each API call to Serpstat consumes units based on the number of results returned and the report type. Queries with large size parameters (size=1000) consume many more units than queries with smaller limits.

Solution: Reduce the 'size' parameter on all queries to the minimum needed for your use case. Use cached data stored in Retool Database for frequently-viewed reports and only call the Serpstat API for scheduled daily refreshes via Retool Workflows. Check Serpstat's API documentation for the unit cost of each endpoint to prioritize which queries to optimize first.

### Position history chart shows incorrect trend direction (improving rankings appear as downward lines)

Cause: In SEO, lower position numbers are better (position 1 = top of SERP). Standard chart axes show higher numbers at the top, making improving rankings (decreasing position numbers) visually appear as a downward trend.

Solution: Invert the y-axis in your Retool Chart component configuration. Set the y-axis to display in reverse (max value lower on screen, min value at top). In Retool's Chart settings, look for y-axis options and enable the 'Reverse' or 'Invert' setting so position 1 appears at the top and position 100 at the bottom, making rank improvements visually clear.

## Frequently asked questions

### Does Serpstat have a native connector in Retool?

No, Serpstat does not have a native connector in Retool. You connect it via a REST API Resource using your Serpstat API token as a URL query parameter. The v4 REST API at api.serpstat.com provides access to domain analytics, keyword rankings, SERP analysis, backlink data, and competitor research — all the core Serpstat data types.

### Which Serpstat plan includes API access?

Serpstat's API access is available on paid plans — Individual, Team, and Agency plans each include different monthly API unit limits. The Lite plan may have limited or no API access. Check your current plan's API unit allowance in Serpstat's account settings under Settings → API. Unit consumption varies by endpoint: some reports cost 1 unit per result row, making the 'size' parameter the key lever for controlling consumption.

### How is Serpstat different from SEMrush for a Retool integration?

Both integrate with Retool via REST API Resource using API key authentication. Serpstat uses a 'token' URL parameter while SEMrush uses a 'key' parameter. Serpstat returns clean JSON responses, while SEMrush returns semicolon-delimited text that requires more parsing work in Retool transformers. For teams on a budget, Serpstat provides similar keyword and domain analytics data at a significantly lower API unit cost per query.

### Can I track rankings for multiple domains in the same Retool dashboard?

Yes. Build a multi-domain tracking view by adding a Multi-Select component to your dashboard where users select multiple domains, then use a Retool Workflow or JavaScript query to fetch rankings for each selected domain from the Serpstat API sequentially. Store all domains' data in the same rank_tracking database table with the domain column for filtering, enabling side-by-side comparison charts and shared keyword discovery.

### How do I handle Serpstat's API rate limits in Retool?

Serpstat enforces API request rate limits in addition to monthly unit quotas. Avoid triggering multiple large queries simultaneously — use Retool event handlers to chain queries sequentially rather than loading all data in parallel on page load. For daily rank imports, use a Retool Workflow with a delay between bulk keyword queries. If you encounter rate limit errors (typically 429 status), add a Wait block in your Workflow between API calls.

---

Source: https://www.rapidevelopers.com/retool-integrations/serpstat
© RapidDev — https://www.rapidevelopers.com/retool-integrations/serpstat
