# Serpstat

- Tool: Bubble
- Difficulty: Beginner
- Time required: 30–45 minutes
- Last updated: July 2026

## TL;DR

Connect Bubble to Serpstat by adding the API Connector plugin, creating a group with your Serpstat token as a Private URL parameter, and sending POST requests to the JSON-RPC endpoint at api.serpstat.com/v4. One button click triggers a query; results appear in a Repeating Group. No OAuth required — just your plan token and an understanding of Serpstat's API unit quota system.

## Build a live SEO dashboard in Bubble without writing backend code

Serpstat gives you programmatic access to keyword data, domain competitive analytics, SERP feature tracking, and backlink metrics. Bubble founders use this to build client-facing SEO dashboards, white-label agency tools, or internal research panels — all without a developer.

The integration has two properties that trip up first-timers. First, Serpstat uses a JSON-RPC style API: instead of different URL paths for different data types, nearly every request is a POST to the same endpoint (`https://api.serpstat.com/v4`) with a `method` field in the JSON body selecting the operation. Second, every call consumes API units from your monthly quota — so building a dashboard that fires queries on every keystroke can exhaust your quota within hours.

Bubble's API Connector handles both properties cleanly: the token stays Private and server-side, and you control exactly when calls fire. The result is a professional SEO tool your clients can use directly from a Bubble app.

## Before you start

- A Bubble account on any paid plan (Starter $32/mo or above) — the API Connector plugin is available on free plans but paid plans give you more workflow runs and Workload Units
- A Serpstat account on a paid plan (Lite $59/mo or above) — the free plan does not include API access
- Your Serpstat API token, found at serpstat.com → Settings → API
- Basic familiarity with Bubble's workflow editor and Repeating Groups

## Step-by-step guide

### 1. Install the API Connector plugin

Open your Bubble app editor. Click the **Plugins** tab in the left sidebar, then click **Add plugins** in the top-right area of the Plugins panel. In the search box, type **API Connector** and look for the plugin published by Bubble (the official one, shown at the top of results). Click **Install** and wait for the confirmation — the plugin appears in your installed list within a few seconds.

The API Connector is Bubble's built-in tool for connecting to any REST or JSON-RPC API. It runs every call from Bubble's servers, so secrets placed in Private fields never reach the user's browser. You will not need any additional plugins for Serpstat.

**Expected result:** The API Connector plugin appears in your installed plugins list and a new 'API Connector' section is visible in the Plugins tab.

### 2. Create the Serpstat API group with a Private token

In the Plugins tab, click **API Connector** to expand its configuration panel. Click **Add another API** to create a new API group. Name it **Serpstat API**.

Under **Shared parameters for all calls**, click **Add shared parameter**, select **URL parameter** as the parameter type, and enter `token` as the parameter name. In the value field, paste your Serpstat API token (found at serpstat.com → Settings → API). Enable the **Private** checkbox next to this parameter.

Marking the parameter Private is the critical security step: Bubble appends the token to every request URL server-side, and the token value is masked in the editor and never sent to the browser. Without Private, the token could be visible in browser network logs.

Leave the base URL blank for now — you will set the full endpoint URL at the individual call level because Serpstat's v4 endpoint is a single URL: `https://api.serpstat.com/v4`.

```
{
  "group_name": "Serpstat API",
  "shared_url_parameters": [
    {
      "name": "token",
      "value": "<your_serpstat_token>",
      "private": true
    }
  ]
}
```

**Expected result:** The Serpstat API group appears in API Connector with a `token` URL parameter marked Private. The token value is masked with asterisks in the editor.

### 3. Add the Initialize Call and discover the response structure

Inside the Serpstat API group, click **Add another call**. Name this call **Get Domain Info**. Set the method to **POST** and enter the endpoint URL: `https://api.serpstat.com/v4`.

Under **Body**, select **JSON** as the body type. Paste the following JSON body — this is a domain info request for a known domain so the Initialize Call returns real data:

```json
{
  "id": 1,
  "method": "SerpstatDomainProcedure.getDomainInfo",
  "params": {
    "domain": "apple.com",
    "se": "g_us"
  }
}
```

Set the call's **Use as** setting to **Data** (since you are retrieving information, not triggering an action). Click **Initialize call** — Bubble sends the request with your Private token appended automatically and shows the raw JSON response in the preview panel.

Expand the response carefully: Serpstat wraps all data inside `result` → `data`. You will see the domain's keyword count, traffic estimate, and other top-level stats. Bubble auto-detects these fields and makes them available in dynamic expressions as `Get Domain Info's result's data's keywords_count`, etc.

This nested structure — `result.data` — is consistent across all Serpstat API v4 calls. Always look inside `result.data` when accessing response values in Bubble expressions.

```
{
  "id": 1,
  "method": "SerpstatDomainProcedure.getDomainInfo",
  "params": {
    "domain": "apple.com",
    "se": "g_us"
  }
}
```

**Expected result:** The Initialize Call succeeds, the response preview shows a JSON object with `result.data` containing domain statistics for apple.com. Bubble lists detected fields including keywords_count, traff, and cost.

### 4. Add the domain keywords call and make parameters dynamic

Click **Add another call** inside the Serpstat API group. Name it **Get Domain Keywords**. Set method to **POST**, endpoint to `https://api.serpstat.com/v4`, and body type to **JSON**.

This time, make the `domain` and `se` parameters dynamic so users can enter any domain and select a search engine. In the JSON body, replace the static values with Bubble's dynamic expression syntax — use angle bracket placeholders in the API Connector editor:

```json
{
  "id": 1,
  "method": "SerpstatDomainProcedure.getDomainKeywords",
  "params": {
    "domain": "<domain>",
    "se": "<se_code>",
    "size": 100
  }
}
```

In Bubble's API Connector body editor, click inside the value for `domain` and toggle it to **dynamic** — this creates a dynamic parameter called `domain` that you will bind to a Text Input when calling this API from a workflow. Do the same for `se_code`.

Set **Use as** to **Data**. Click **Initialize call**, filling in `apple.com` for domain and `g_us` for se_code in the Initialize Call dialog (these are test values only — they won't appear in production).

Once initialized, this call exposes a list of keyword objects under `result.data`, each with fields like `keyword`, `found_results`, `cost`, `competition`, and `traff`. Bubble detects all of these as accessible fields.

```
{
  "id": 1,
  "method": "SerpstatDomainProcedure.getDomainKeywords",
  "params": {
    "domain": "<domain>",
    "se": "<se_code>",
    "size": 100
  }
}
```

**Expected result:** The Get Domain Keywords call is initialized successfully with detected fields including keyword, found_results, cost, competition, and traff visible in the response preview.

### 5. Build the search UI with a button-triggered workflow

On your Bubble page, add these elements:

1. A **Text Input** element — Label it 'Enter domain (e.g. competitor.com)'. Give it the ID name `DomainInput`.
2. A **Dropdown** element — Label it 'Search engine'. Add options: g_us (US), g_uk (UK), g_de (Germany). These must be the exact Serpstat `se` codes, not display names, OR you can map them: store the display name as text but use the hidden code as value.
3. A **Button** — Label it 'Run Analysis'. This is intentional: triggering Serpstat queries on every keystroke burns API units. One button click = one query.
4. A **Repeating Group** — Set its Type of content to **Get Domain Keywords** (the API Connector data type). Set its Data source initially to empty.

Now wire up the workflow: click the **Run Analysis** button, go to its workflow. Add action **Plugins → Serpstat API - Get Domain Keywords**. In the action parameters, set `domain` = `DomainInput's value` and `se_code` = `SearchEngineDropdown's value`.

After this action, add a **Display data in Repeating Group** action pointing to your Repeating Group and set the data to **Result of step 1** (the API call result's `result`'s `data`).

Inside the Repeating Group, add Text elements and bind them: `Current cell's keyword`, `Current cell's found_results`, `Current cell's cost`, `Current cell's competition`.

For competitive research, you can add a second button 'Get Competitors' that fires the `getDomainCompetitors` method in the same way.

**Expected result:** Clicking Run Analysis fires the Serpstat API call and populates the Repeating Group with keyword data for the entered domain, showing keyword, search volume, CPC, and competition score for each result.

### 6. Add privacy rules and protect API unit quota

If your Bubble app stores any Serpstat results in the database (e.g., for caching or saving client reports), configure Data tab → Privacy rules for that Data Type. Without privacy rules, all rows are readable by any logged-in user of your app. Set a rule: 'Find this in searches: When Current User is in Admin role' — or restrict to the user who created the record.

For quota protection, implement a 'last query time' Custom State on the page:
1. Add a Custom State to the page of type **date**, named `LastQueryTime`.
2. In the Run Analysis button workflow, add a **Condition** at the start: Only run if `Current date/time > LastQueryTime + 10 seconds`. This prevents users from spamming the button.
3. After the API call action, add a **Set Custom State** action setting `LastQueryTime` to the current date/time.

Displaying the API unit cost estimate in a tooltip on the button is also good practice: Serpstat's getDomainKeywords with size=100 costs more units than getDomainInfo. Check your unit balance at serpstat.com → Settings → API after initial testing to understand consumption rates.

Workload Units in Bubble are also consumed by each API call, workflow step, and database operation. For a public-facing tool with many users, consider caching Serpstat results in a Bubble Data Type with a 'cached_at' timestamp, and only re-querying if the cache is older than 24 hours.

**Expected result:** Privacy rules are configured for any Serpstat data stored in the database. The Run Analysis button has a 10-second cooldown via Custom State, preventing quota exhaustion from repeated clicks.

## Best practices

- Always mark the `token` URL parameter as Private in the API Connector group — this is the only mechanism keeping your Serpstat key server-side and out of browser network logs.
- Trigger Serpstat queries from a button click, never from a text input's onChange event. Each query consumes API units, and units are a finite daily resource shared across all users of your app.
- Cache Serpstat results in a Bubble Data Type with a `cached_at` timestamp. For a dashboard checking the same client domains repeatedly, retrieve cached data if it's less than 24 hours old before firing a new API call.
- Use the Initialize Call every time you add a new Serpstat method — do not guess at the response structure. Serpstat's `result.data` nesting level and field names vary slightly between methods.
- Create separate API Connector calls for each Serpstat method (getDomainInfo, getDomainKeywords, getDomainCompetitors) rather than building one generic call with a dynamic method field. Separate calls allow Bubble to auto-detect and name the response fields correctly for each data type.
- Add privacy rules to any Bubble Data Type used to cache Serpstat results. Agency client data (competitor analysis, keyword rankings) should be readable only by the client's own account, not by all logged-in users of your app.
- Monitor your Serpstat API unit balance weekly during the first month of a new integration, especially if the app is public-facing. Build a Bubble workflow that queries the Serpstat account stats endpoint daily and stores the remaining unit count in App Data so you can display a warning when quota is running low.
- Document the Serpstat API token storage location for your team. If the token is rotated (e.g., due to a security incident), the Private field value must be updated manually in the API Connector — there is no automatic rotation mechanism in Bubble.

## Use cases

### Client SEO reporting dashboard

Agency founders build a Bubble app where clients enter their domain and instantly see keyword rankings, estimated traffic, and top competing domains — all pulled live from Serpstat. Data refreshes on demand with a single button click.

Prompt example:

```
Build a Bubble page with a text input for domain name, a dropdown for search engine (g_us, g_uk, g_de), a 'Run Analysis' button, and a Repeating Group that shows keyword, monthly search volume, CPC, and competition score from Serpstat's getDomainKeywords response.
```

### Competitor intelligence tool

SaaS founders building marketing tools pull competitor domain data from Serpstat to show users which sites compete for the same keywords, enabling strategic content planning without leaving the Bubble app.

Prompt example:

```
Create a Bubble workflow that calls Serpstat's getDomainCompetitors method for a given domain, then displays the top 10 competitors in a Repeating Group with their organic traffic estimates and keyword overlap counts.
```

### Keyword research panel

Content-focused apps let users type a seed keyword and retrieve related keyword suggestions with search volume and difficulty scores — combining Serpstat's keyword API with Bubble's database to save favorite keywords for later use.

Prompt example:

```
Build a Bubble keyword research tool: user types a seed keyword, clicks Search, and sees a Repeating Group of related keywords from Serpstat getKeywordRelatedKeywords, with a 'Save' button that stores selected keywords to a Bubble Data Type called Saved Keywords.
```

## Troubleshooting

### Initialize Call fails with 'There was an issue setting up your call' error in Bubble

Cause: The API Connector cannot reach the Serpstat endpoint, or the token URL parameter is not being appended correctly. This often happens if the `token` parameter was added as a Header instead of a URL parameter.

Solution: Open the Serpstat API group settings and confirm the `token` is listed under URL Parameters (not Headers) and has the Private checkbox checked. Then retry the Initialize Call. If the error persists, open your browser's developer tools Network tab while triggering the Initialize Call and inspect the outgoing request URL — the token should appear as a query string parameter.

### Initialize Call returns a 200 response but the response body contains an `error` field instead of `result.data`

Cause: The `se` (search engine) code is invalid, or the `method` name is misspelled. Serpstat returns HTTP 200 even for application-level errors, wrapping them in an `error` field instead of `result`.

Solution: Check that the `se` value is exactly `g_us`, `g_uk`, or `g_de` — not 'google_us', 'US', or 'google'. Verify the `method` field spells out the full procedure name including the class prefix: `SerpstatDomainProcedure.getDomainKeywords`, not just `getDomainKeywords`. Re-run Initialize Call after correcting these values.

### Repeating Group is empty after the workflow runs, even though the workflow step shows no error

Cause: The data source is being set to the top-level API call result instead of the nested `result.data` array. Serpstat wraps all data two levels deep.

Solution: In the Display data in Repeating Group action, set the data to: Result of step 1 (the API call) → result → data. In Bubble's expression builder this looks like `Result of step 1's result's data`. If the Repeating Group type is set to the API Connector data type, also ensure the list field is mapped to `data`, not to `result` as a whole.

### API calls stop working and the response shows a quota exceeded error

Cause: Your Serpstat account's daily API unit quota has been exhausted. This can happen if workflows fire on input change rather than on button click, or if many users are triggering queries simultaneously.

Solution: Switch all Serpstat query triggers to a button click (not input change). Add the 10-second cooldown Custom State described in Step 6. Consider caching results in a Bubble Data Type and only re-querying if the cache is older than 24 hours. Check your remaining units at serpstat.com → Settings → API.

### Initialize Call works but production calls from workflows return 401 Unauthorized

Cause: The Private token parameter is not being included in workflow-triggered calls, or the API Connector group was duplicated/recreated without the Private flag.

Solution: Open the Serpstat API group in the API Connector and verify the `token` URL parameter still has Private checked. If you recently exported and reimported the app, Private parameters may need to be re-entered — their values are intentionally not exported for security reasons.

## Frequently asked questions

### Do I need a paid Serpstat plan to use the API?

Yes. The free Serpstat plan does not include API access. You need at least the Lite plan (starting at $59/month) to obtain an API token and make API calls. Check serpstat.com/pricing for current plan details and API unit quotas per tier.

### Why does Serpstat use POST requests for data retrieval instead of GET?

Serpstat's API v4 uses JSON-RPC style, which is a protocol where the operation type (method name) is specified in the request body rather than the URL path. This is different from standard REST APIs where GET retrieves data and POST creates data. In Bubble's API Connector, you set these calls to POST with a JSON body — the `method` field in the body tells Serpstat which operation to run.

### What happens if my Serpstat API unit quota runs out mid-day?

Serpstat returns a 200 HTTP status code even when the quota is exhausted, but the response body contains an `error` field instead of `result.data`. Bubble won't show a red workflow error — your Repeating Group simply appears empty. Build a quota monitoring step (query Serpstat's account stats endpoint) and display a user-visible warning when units fall below a threshold.

### Can I build a public-facing SEO tool on Bubble using Serpstat?

Yes, but be aware that every user query consumes your Serpstat API unit quota. If 100 users each run 5 queries per day, that's 500 unit calls against your account's daily limit. Implement the caching pattern from Step 6 and the cooldown Custom State. For very high-traffic tools, consider upgrading to a Serpstat plan with a larger unit quota or implementing result caching with a 24-hour refresh window.

### How do I handle Serpstat's search engine codes in a user-friendly dropdown?

Create a Bubble Dropdown element and add options using display name / value pairs: show the user 'Google US' but use `g_us` as the option's value. In the API Connector body JSON, bind the `se` parameter to the Dropdown's value (the code, not the label). This keeps the user experience clean while sending the exact code Serpstat requires.

### What's the difference between Serpstat's getDomainInfo and getDomainKeywords methods?

getDomainInfo returns a single summary object for a domain — total keyword count, estimated organic traffic, traffic cost estimate, and competitor count. It's a fast, low-unit-cost call ideal for a dashboard overview tile. getDomainKeywords returns an array of individual keyword records for the domain (up to the `size` limit you specify), showing each keyword the domain ranks for. Use getDomainInfo for quick stats and getDomainKeywords when users want to drill into the full keyword list.

---

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