# Ubersuggest

- Tool: Bubble
- Difficulty: Intermediate
- Time required: 2–3 hours
- Last updated: July 2026

## TL;DR

Connect Bubble to Ubersuggest by adding the API Connector plugin, setting the base URL to https://app.neilpatel.com/api, and placing your API key in a Private Authorization header. Bubble proxies every request server-side so your key never reaches the browser. Cache results in a Keyword_Cache Data Type to protect shared credit pools — credit burn on team apps is the top support issue for this integration.

## Build a keyword research panel inside your Bubble app

Ubersuggest's API lives at https://app.neilpatel.com/api and is gated behind paid plans (Individual at $12/mo and above). It returns keyword volume, CPC, and SEO difficulty scores — data that SEO teams and content strategists use every day. By pulling this data directly into a Bubble app, you can build an in-app keyword research panel or content-brief generator that lets your team work inside the tools they already use without requiring each person to have a separate Ubersuggest login.

Bubble's API Connector is the right tool for this job because it runs calls from Bubble's servers, handling authentication server-side. One important operational reality to plan for: Ubersuggest credits are shared across your entire account. If your Bubble app triggers a live API call on every keystroke in a search box, a five-person team can exhaust a month's credits in a single afternoon. Building a caching layer in a Bubble Data Type is not optional for shared team apps — it is the most critical architectural decision in this integration.

## Before you start

- An active Ubersuggest Individual plan or higher ($12/mo+) — the free tier does not include API access
- Your Ubersuggest API key from app.neilpatel.com Account Settings → API
- A Bubble account with an existing app (any plan — the API Connector works on the free Bubble tier for outbound calls)
- The API Connector plugin installed in your Bubble app (free, by Bubble)

## Step-by-step guide

### 1. Subscribe to Ubersuggest and retrieve your API key

Before you can make a single API call, you need a paid Ubersuggest plan. Log in to app.neilpatel.com, click your account avatar in the top-right corner, and navigate to Account Settings. Look for the API section within settings — this is where Neil Patel exposes your API key for paid subscribers. Copy the key and store it somewhere safe (a password manager works well). If you do not see an API section, your account is on the free tier and you will need to upgrade to the Individual plan ($12/mo) or higher before proceeding. Note that Ubersuggest's API documentation is not prominently publicised — endpoint paths like /keywords/suggestions and /domain/overview should be verified directly at app.neilpatel.com/api or by inspecting network requests in your browser's developer tools while using the Ubersuggest web app.

**Expected result:** You have your Ubersuggest API key copied and your plan tier confirmed as Individual or above.

### 2. Install the API Connector and configure the Ubersuggest connection

In your Bubble app editor, click the Plugins tab in the left sidebar, then click the blue 'Add plugins' button. Search for 'API Connector' — this is the free official plugin by Bubble. Install it. Once installed, the API Connector appears in your Plugins tab list. Click on it to open its configuration panel, then click 'Add another API'. Name this API 'Ubersuggest'. In the 'Base URL' field, enter: https://app.neilpatel.com/api

Next, add a Shared Header that will apply to every call you create under this API. Click 'Add a shared header'. In the Key field, type: Authorization. In the Value field, paste your Ubersuggest API key directly. Then check the 'Private' checkbox next to this header. This is the critical security step — the Private checkbox tells Bubble to keep this header on the server side and never expose it in responses sent to the browser. Your API key will not appear in page source or browser network logs.

```
{
  "api_name": "Ubersuggest",
  "base_url": "https://app.neilpatel.com/api",
  "shared_headers": [
    {
      "key": "Authorization",
      "value": "YOUR_API_KEY_HERE",
      "private": true
    }
  ]
}
```

**Expected result:** The API Connector shows 'Ubersuggest' listed with a Private Authorization header. No calls have been added yet.

### 3. Add the keyword suggestions API call and initialize it

Click 'Add another call' under your Ubersuggest API in the API Connector. Name this call 'keyword_suggestions'. Set the method to GET. In the URL path field (appended to the base URL), enter: /keywords/suggestions — this gives the full URL https://app.neilpatel.com/api/keywords/suggestions. Under Parameters, click 'Add parameter'. Set the Key to 'keyword' and leave the Value as a placeholder like 'seo tools' — do NOT check Private for this parameter since it is the user's search query, not a secret.

Now set 'Use as' to 'Data' in the dropdown. This tells Bubble to treat the response as a data source that can feed a Repeating Group or 'Get data from an external API' expression. Before saving, click 'Initialize call'. Bubble will make a live request to the Ubersuggest API using your Authorization header and the test keyword value 'seo tools'. It is essential to use a high-traffic keyword like 'seo tools' here — if you use an obscure or misspelled phrase that returns an empty array, Bubble cannot detect the response shape and field types will not populate correctly. After a successful response, Bubble lists the detected fields (keyword, search_volume, cpc, seo_difficulty, etc.) with their types. Verify these look correct before clicking Save.

```
GET https://app.neilpatel.com/api/keywords/suggestions
Headers:
  Authorization: <private>
Parameters:
  keyword: seo tools

Example response shape:
{
  "keywords": [
    {
      "keyword": "seo tools",
      "search_volume": 90500,
      "cpc": 4.20,
      "seo_difficulty": 67,
      "paid_difficulty": 55
    }
  ]
}
```

**Expected result:** The keyword_suggestions call shows as initialized with detected fields: keyword (text), search_volume (number), cpc (number), seo_difficulty (number). Status shows green.

### 4. Create the Keyword_Cache Data Type to store results

Building a caching layer is essential for any Bubble app where more than one person will use the keyword search feature. Because Ubersuggest credits are pooled at the account level, every live API call draws from the same monthly budget. Without caching, a five-person team triggering searches throughout the day can exhaust credits well before the billing cycle ends.

Go to the Data tab in your Bubble editor. Click 'New type' and name it 'Keyword_Cache'. Add the following fields by clicking 'Create a new field' for each:
- keyword: Text (the search term)
- volume: Number (search_volume from API)
- csd: Number (seo_difficulty from API)
- cpc: Number (cost per click from API)
- paid_difficulty: Number
- fetched_date: Date (when this cache entry was created)

Also go to the Data tab → Privacy section for this new Data Type. Set appropriate privacy rules — at minimum, ensure only your app's logged-in users (or admin roles) can read and search these records. By default in Bubble, all Data Types without privacy rules are accessible via the Bubble API and Data API, which is a security gap you want to close immediately.

```
Data Type: Keyword_Cache
Fields:
  - keyword: Text
  - volume: Number
  - csd: Number (SEO difficulty)
  - cpc: Number
  - paid_difficulty: Number
  - fetched_date: Date

Privacy rule:
  - 'Everyone else' → Read: No
  - 'Logged-in users' → Find in searches: Yes, Read: Yes
```

**Expected result:** The Keyword_Cache Data Type appears in the Data tab with all six fields and a privacy rule preventing public access.

### 5. Build the cache-first Workflow for keyword lookups

The search workflow is the heart of this integration. It should always check the cache before calling the API. Here is how to build it:

Add a Search Input element and a Button to your page. Also add a Repeating Group with Data Type set to Keyword_Cache and Data source set to 'Do a search for Keyword_Cache items where keyword = Search Input's value'.

For the Button's click Workflow, add these steps in order:
1. First, check if a cached result exists: Add a 'Only when' condition on the next step — 'Search for Keyword_Cache items where keyword = Search Input's value AND fetched_date > current date minus 7 days' Count is 0. This means the next step only runs if no fresh cache entry exists.
2. Step 1 (only when no fresh cache): Run the 'keyword_suggestions' API Connector call with keyword parameter = Search Input's value.
3. Step 2: Create a new Keyword_Cache thing with: keyword = Search Input's value, volume = Result of Step 1's search_volume (first item), csd = Result of Step 1's seo_difficulty (first item), cpc = Result of Step 1's cpc (first item), fetched_date = Current date/time.

The Repeating Group bound to Keyword_Cache will automatically refresh and show the newly created record, or the existing cached record if it was already fresh. For teams that want a full keyword suggestion list (multiple rows per keyword), store each suggestion as a separate Keyword_Cache record and filter the Repeating Group by keyword = Search Input's value.

```
Workflow: Button 'Search' clicked

Step 1 [Only when: search for Keyword_Cache where keyword=SearchInput's value AND fetched_date > Current date/time - 7 days, count = 0]:
  Action: Call API → Ubersuggest - keyword_suggestions
  Parameter: keyword = SearchInput's value

Step 2 [Only when: Step 1 was run]:
  Action: Create a new thing → Keyword_Cache
    keyword: SearchInput's value
    volume: Result of Step 1's keywords:first item's search_volume
    csd: Result of Step 1's keywords:first item's seo_difficulty
    cpc: Result of Step 1's keywords:first item's cpc
    fetched_date: Current date/time
```

**Expected result:** Clicking the Search button for a new keyword calls the API, creates a Keyword_Cache record, and the Repeating Group displays the result. Clicking it again for the same keyword within 7 days skips the API call entirely.

### 6. Bind the Repeating Group and display keyword metrics

With caching in place, the Repeating Group is straightforward to configure. Select your Repeating Group on the canvas. In its Properties panel, confirm:
- Type of content: Keyword_Cache
- Data source: Do a search for Keyword_Cache items where keyword = SearchInput's value, sorted by volume descending

Inside the Repeating Group's cell, add Text elements for each metric. For the keyword field, set the text to 'Current cell's Keyword_Cache's keyword'. For volume, add a Text with 'Current cell's Keyword_Cache's volume' and format as number. For SEO difficulty, show the CSD number and optionally add a Conditional on the text element: if csd < 40, text color = green; if csd is between 40 and 70, text color = orange; if csd > 70, text color = red. This gives your team an at-a-glance difficulty signal.

For CPC, show the value formatted as currency. Add a 'Last updated' text showing the fetched_date formatted as 'MMM D, YYYY' so users know when the data was last refreshed from Ubersuggest. Add a separate 'Force Refresh' button that deletes the current Keyword_Cache record for the search term and re-runs the API call — this gives users an escape valve when they know the data is stale without waiting for the 7-day expiry. RapidDev's team has built dozens of Bubble data-sourcing panels with external API caching patterns like this — if you need help optimizing for higher team volumes or multi-keyword batch processing, reach out at rapidevelopers.com/contact.

```
Repeating Group settings:
  Type of content: Keyword_Cache
  Data source: Search for Keyword_Cache where keyword = SearchInput's value
  Sort by: volume, descending

Cell contents:
  Text 1: Current cell's Keyword_Cache's keyword
  Text 2: Current cell's Keyword_Cache's volume (format: number)
  Text 3: Current cell's Keyword_Cache's csd
    Conditional: if csd < 40 → color green
    Conditional: if csd ≥ 40 AND ≤ 70 → color orange  
    Conditional: if csd > 70 → color red
  Text 4: Current cell's Keyword_Cache's cpc (format: $#,##0.00)
  Text 5: 'Updated: ' + Current cell's Keyword_Cache's fetched_date (format: MMM D, YYYY)
```

**Expected result:** The Repeating Group displays keyword rows with volume, CSD (color-coded), CPC, and cache date. The panel is usable by the whole team without individual Ubersuggest logins.

## Best practices

- Always mark the Authorization header Private in the API Connector — never put the Ubersuggest API key in a URL parameter or unprotected header, as it would be visible in browser network logs.
- Cache all keyword results in a Keyword_Cache Data Type with a fetched_date field and expire entries after 7 days. Ubersuggest data changes slowly enough that weekly refreshes are sufficient, and this prevents unexpected credit exhaustion on shared team apps.
- Use high-traffic test keywords like 'seo tools' or 'content marketing' during API Connector initialization — empty responses from obscure keywords prevent Bubble from detecting field types correctly.
- Set privacy rules on the Keyword_Cache Data Type immediately after creating it. By default, Bubble Data Types without privacy rules are accessible via the Data API, which could expose your team's keyword research strategy.
- Trigger API calls from button clicks rather than from input change events. Debouncing in Bubble (custom state + delayed workflow) is possible but more complex than a simple Search button — prefer the button pattern for straightforward builds.
- Store Ubersuggest endpoint paths as Bubble App Constants if you use multiple endpoints (e.g., /keywords/suggestions, /domain/overview). If Ubersuggest changes an endpoint path, you update the constant once rather than editing each API Connector call.
- Monitor your Ubersuggest credit usage regularly via the account dashboard at app.neilpatel.com. Add a Bubble admin page that displays the oldest and newest cache entries per keyword — this lets you quickly identify which searches are consuming the most credits.
- Add a 'Workload Units' note in your Bubble app documentation: every API Connector call consumes WU on Bubble's post-2023 pricing plan. Cache-first patterns reduce both Ubersuggest credits and Bubble WU simultaneously.

## Use cases

### In-app keyword research panel

Let your content team look up keyword volume, CPC, and SEO difficulty inside your Bubble project management app without leaving the platform or needing individual Ubersuggest accounts. Results are fetched once and cached, so repeated searches for the same term cost zero additional credits.

Prompt example:

```
Build a keyword research page in my Bubble app that lets users type a keyword, fetches data from Ubersuggest, and displays volume, CPC, and SEO difficulty in a table — caching each result so repeated searches don't use credits.
```

### Content brief generator with SEO data

When a writer creates a new content brief in your Bubble app, automatically fetch keyword suggestions and competition data from Ubersuggest and attach them to the brief record. Writers get actionable SEO context without switching tools.

Prompt example:

```
When a new Brief record is created in my Bubble app, automatically call the Ubersuggest API with the brief's target keyword, and save the top 10 keyword suggestions (with volume and CSD) to the Brief's related Keyword_Cache records.
```

### Competitor domain overview dashboard

Track competitor domains' SEO health over time by pulling domain overview data from Ubersuggest on a weekly schedule. Store the results in a Data Type and display trends in a Bubble chart element so your team can spot ranking shifts without manual lookups.

Prompt example:

```
Build a competitor tracker in Bubble that runs a weekly Backend Workflow to call Ubersuggest's domain overview endpoint for a list of competitor URLs and saves DA, traffic estimates, and keyword count to a CompetitorSnapshot Data Type for trend charting.
```

## Troubleshooting

### Initialize call fails with 'There was an issue setting up your call' or returns empty data

Cause: The most common cause is using an obscure test keyword that returns an empty suggestions array. Bubble cannot detect field types from an empty response. A secondary cause is a 401 from Ubersuggest when the account is on the free tier.

Solution: Use a high-traffic keyword like 'seo tools' or 'keyword research' for the initialize call. These return non-empty arrays that Bubble can parse. If you still get a 401, verify your Ubersuggest account is on the Individual plan or higher — the API is not available on free accounts. Check that the Authorization header value is exactly your API key, not 'Bearer YOUR_KEY' (Ubersuggest may not use the Bearer prefix — verify the exact auth format in the API docs at app.neilpatel.com/api).

### Credits exhausted within hours of launch, far faster than expected

Cause: The Bubble workflow is calling the Ubersuggest API on every keystroke in the search input rather than on button click, or the Keyword_Cache check is missing and every search triggers a live API call.

Solution: Audit the element that triggers the keyword workflow. If it fires on 'Input's value is changed', switch it to trigger on a dedicated Search button click instead. Verify that Step 1 of the workflow has the correct 'Only when' condition checking for a fresh cache entry. Go to Bubble's Logs tab → API Connector logs to see how many calls are being made and from which workflow step.

### Keyword data appears in the API response but fields show blank in the Repeating Group

Cause: The API Connector response shape has nested arrays (the keyword suggestions are inside a 'keywords' array), and Bubble's field accessor needs to be set to the correct nesting level. The Repeating Group data source may also be pointing to the wrong level of the response.

Solution: During the Initialize call step, look carefully at the detected field structure. If Bubble detected a field called 'keywords' of type 'list of keyword', you need to set your Repeating Group's data source to 'Get data from external API → Ubersuggest keyword_suggestions's keywords'. Then bind cell text elements to 'Current cell's keyword's search_volume' rather than directly to the top-level response. If fields were not detected correctly during initialization, delete the call, re-add it, and re-initialize with a keyword that returns a full, non-empty response.

### 401 Unauthorized error even though the API key appears correct

Cause: Ubersuggest's free tier returns 401 with no meaningful error message rather than a plan-level access message. The key may also have been regenerated in the Ubersuggest dashboard since setup.

Solution: Log in to app.neilpatel.com, go to Account Settings → API, and confirm your plan is Individual or above. Copy the API key fresh from the dashboard and update the Private header value in the API Connector. Save and re-initialize the call. Do not add a 'Bearer ' prefix unless the Ubersuggest API documentation explicitly requires it.

## Frequently asked questions

### Does Ubersuggest have a public API?

Yes, Ubersuggest has an API accessible at app.neilpatel.com/api, but it is not prominently documented. It is available on paid plans starting with the Individual tier at $12/month. The API is not available on the free Ubersuggest account. Endpoint paths such as /keywords/suggestions and /domain/overview can be confirmed at the API documentation page or by inspecting network requests in the Ubersuggest web app.

### Will my Ubersuggest API key be exposed to users of my Bubble app?

No — as long as you place the key in a header marked Private in the API Connector. Bubble routes all API Connector calls through its own servers, and Private headers are stripped from all client-side responses. The key is stored encrypted in Bubble's backend and never appears in page source, browser network logs, or JavaScript bundles.

### What happens if our team exhausts Ubersuggest credits mid-month?

The API will return errors or empty responses until the credits reset at the start of the next billing cycle. This is why caching in a Keyword_Cache Data Type is critical for team apps. Monitor usage in the Ubersuggest account dashboard and consider upgrading your plan if your team regularly approaches the credit limit. You can also build an admin alert in Bubble that notifies you when the cache miss rate (live API calls) exceeds a threshold.

### Can I display keyword data for multiple keywords at once in a Bubble Repeating Group?

Yes. The recommended approach is to run the cache-check-and-fill workflow for each keyword in a list using a recursive Backend Workflow or by storing multiple Keyword_Cache records (one per keyword per search session). The Repeating Group can then be filtered by a list of keywords. For batch processing (researching 50+ keywords at once), build a Backend Workflow that loops through the keyword list, calling the API and caching results with a 1-second delay between calls to respect rate limits.

### Do I need a paid Bubble plan to use the Ubersuggest API Connector?

No — the API Connector plugin for outbound calls works on Bubble's free tier. You only need a paid Bubble plan (Starter $32/mo+) if you want to use Backend Workflows for scheduled cache refreshes or recursive batch processing. For basic on-demand keyword searches with client-triggered workflows, the free Bubble tier is sufficient.

### Why does the initialize call sometimes fail even though my API key is correct?

The initialize call must return a non-empty JSON response with at least one item in the suggestions array. If you use an obscure or very new keyword that Ubersuggest has no data for, the response may be an empty array — Bubble cannot detect field types from an empty response and will report an initialization error. Always use popular, high-volume keywords like 'seo tools' or 'digital marketing' for the initialization step. You can change the default parameter value later after field types are established.

---

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