Skip to main content
RapidDev - Software Development Agency
bubble-integrationsBubble API Connector

SEMrush

Connect Bubble to SEMrush by adding your API key as a Private URL parameter named `key` (not an Authorization header) in the API Connector. The critical challenge: SEMrush returns semicolon-delimited plain text for most reports — not JSON. Parsing this format requires the Toolbox plugin's Server Script action in a Backend Workflow. SEMrush API access requires a Pro plan or above.

What you'll learn

  • How to add a SEMrush API key as a Private URL parameter in Bubble's API Connector
  • Why SEMrush returns semicolon-delimited text instead of JSON and how to parse it in Bubble
  • How to use the Toolbox plugin's Server Script action to convert delimited text to usable data
  • How to build a competitive SEO intelligence dashboard with domain traffic and keyword metrics
  • How to cache SEMrush results in a Bubble data type to control API unit consumption
  • How to use display_limit and other parameters to manage SEMrush API unit costs
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate18 min read2–3 hoursMarketingLast updated July 2026RapidDev Engineering Team
TL;DR

Connect Bubble to SEMrush by adding your API key as a Private URL parameter named `key` (not an Authorization header) in the API Connector. The critical challenge: SEMrush returns semicolon-delimited plain text for most reports — not JSON. Parsing this format requires the Toolbox plugin's Server Script action in a Backend Workflow. SEMrush API access requires a Pro plan or above.

Quick facts about this guide
FactValue
ToolSEMrush
CategoryMarketing
MethodBubble API Connector
DifficultyIntermediate
Time required2–3 hours
Last updatedJuly 2026

SEMrush + Bubble: Competitive SEO Intelligence Dashboard

SEMrush is one of the most valuable SEO tools to surface in a Bubble app — but it's also one of the more technically unusual APIs to integrate. Two things distinguish it from standard REST APIs: the API key goes in the URL query string (not an Authorization header), and responses come back as semicolon-delimited text files, not JSON. Bubble's API Connector expects JSON responses, so the text format requires an extra parsing step.

The good news: Bubble's API Connector can still keep your API key secure. URL parameters can be marked Private just like headers — the key never reaches the browser even though it's technically a query string parameter. This is the same privacy guarantee as header-based authentication for all practical purposes.

For the text parsing challenge, the most reliable Bubble-native solution is the Toolbox plugin's Server Script action. A Server Script can receive the raw SEMrush text response, split it by newlines and semicolons, and return a structured object that subsequent workflow steps can use. This runs entirely server-side inside Bubble's infrastructure.

The use case most Bubble founders want is a competitive SEO intelligence dashboard: organic traffic estimates for your domain alongside 2-3 competitor domains, keyword ranking counts, and ad spend estimates. Since SEMrush charges API units per call (and per row for some reports), caching results in a Bubble database and refreshing daily rather than on every page load is essential for cost management.

Integration method

Bubble API Connector

Call the SEMrush API at https://api.semrush.com with the API key as a Private URL parameter, then parse the semicolon-delimited text response using the Toolbox plugin's Server Script action in a Backend Workflow.

Prerequisites

  • A SEMrush account on the Pro plan or above — SEMrush API access is not available on the free plan. API units are allocated per plan (Pro, Guru, Business)
  • Your SEMrush API key, found at SEMrush Account Settings → API Key (requires a paid subscription)
  • The API Connector plugin installed in your Bubble app (Plugins tab → Add plugins → 'API Connector' by Bubble)
  • The Toolbox plugin installed in your Bubble app (Plugins tab → Add plugins → search 'Toolbox' — free, by Bubble)
  • A Bubble app on a paid plan if using Backend Workflows for scheduled data refresh (Starter or above)

Step-by-step guide

1

Understand SEMrush API response format before configuring Bubble

Before opening Bubble, test the SEMrush API in your browser to understand what you're working with. Open this URL (replace YOUR_API_KEY and example.com with your own): `https://api.semrush.com/?type=domain_ranks&key=YOUR_API_KEY&domain=example.com&database=us&export_columns=Or,Ot,Oc,Ad,At,Ac` You'll see a response like: ``` Or;Ot;Oc;Ad;At;Ac 12345;450000;3.50;200;15000;2.00 ``` The first line is a semicolon-delimited header row. The second line (and any following lines) are the data rows. Each value maps to its column header. Bubble's API Connector cannot parse this format natively — it expects JSON. This is why parsing is a mandatory step, not optional. Also note the domain format: SEMrush requires the bare domain without protocol or trailing slash. Enter `example.com` not `https://www.example.com/`. This is the #1 cause of the 'ERROR 50: NOTHING FOUND' response — the domain format is wrong, not a data availability issue. The column codes for domain_ranks report: Or = organic keywords count, Ot = organic traffic estimate, Oc = organic traffic cost (in USD), Ad = paid keywords, At = paid traffic, Ac = paid traffic cost.

semrush-api-response-format.txt
1// SEMrush API response format — semicolon-delimited text
2// Example: GET https://api.semrush.com/?type=domain_ranks&key=API_KEY&domain=example.com&database=us
3
4// Response (plain text, NOT JSON):
5Or;Ot;Oc;Ad;At;Ac
612345;450000;3.50;200;15000;2.00
7
8// Column meanings for domain_ranks:
9// Or = organic keyword count
10// Ot = estimated monthly organic traffic
11// Oc = organic traffic cost (USD)
12// Ad = paid keyword count
13// At = estimated paid traffic
14// Ac = paid traffic cost (USD)
15
16// For domain_organic (keyword list) — costs units per row:
17// Keyword positions report returns one data row per keyword
18// Use display_limit=50 to limit rows and control unit consumption
19
20// ERROR 50 example (domain not found or wrong format):
21// ERROR 50 :: NOTHING FOUND

Pro tip: Before configuring Bubble, test your API key and domain by pasting the full URL into a browser. If you see 'ERROR 50 :: NOTHING FOUND', verify the domain format is bare (example.com), the database parameter matches the correct country (us, uk, de, etc.), and your SEMrush account has data for that domain.

Expected result: Browser shows a two-line text response with a header row and data row. The API key works, the domain returns data, and you understand the semicolon-delimited format you'll need to parse in Bubble.

2

Configure the API Connector with the SEMrush API key as a Private URL parameter

In Bubble, click the Plugins tab → 'API Connector'. Click 'Add another API'. Name it 'SEMrush API'. Set the base URL to `https://api.semrush.com`. Do NOT add any shared headers. SEMrush authentication is done entirely via URL parameters, not headers. The API does not accept an Authorization header. Click 'Add a call'. Name it 'Get Domain Ranks'. Set method to GET, path to `/` (the SEMrush API uses a single base endpoint with the report type as a parameter). Add URL parameters: - `type` — value: `domain_ranks` (selects the report type) - `key` — value: your SEMrush API key — IMPORTANT: enable the **Private** checkbox on this parameter. In Bubble's API Connector, URL parameters can be marked Private just like headers, which keeps the key on Bubble's server and out of the browser. Enter your actual key value here. - `domain` — leave as a dynamic parameter (you'll pass domain names from your Bubble UI) - `database` — value: `us` (or your target country: uk, de, fr, au, etc.) - `export_columns` — value: `Or,Ot,Oc,Ad,At,Ac` (select only the columns you need) - `display_limit` — value: `1` (domain_ranks always returns 1 row; for keyword-level reports, set this to 50 to limit unit consumption) IMPORTANT: Do NOT click 'Initialize call' yet. SEMrush returns plain text, not JSON. If you try to Initialize now, Bubble will fail to parse the response and show 'There was an issue setting up your call'. You'll handle initialization after adding the parsing step.

semrush-api-connector-config.json
1// API Connector: SEMrush API
2{
3 "api_name": "SEMrush API",
4 "base_url": "https://api.semrush.com",
5 "authentication": "none",
6 "calls": [
7 {
8 "name": "Get Domain Ranks",
9 "method": "GET",
10 "path": "/",
11 "params": [
12 { "name": "type", "value": "domain_ranks" },
13 {
14 "name": "key",
15 "value": "YOUR_SEMRUSH_API_KEY",
16 "private": true
17 },
18 { "name": "domain", "value": "<dynamic>" },
19 { "name": "database", "value": "us" },
20 { "name": "export_columns", "value": "Or,Ot,Oc,Ad,At,Ac" },
21 { "name": "display_limit", "value": "1" }
22 ]
23 }
24 ]
25}

Pro tip: To verify the API key is correctly stored without exposing it, check that the `key` parameter row shows a lock icon or 'Private' indicator in the API Connector interface after enabling the checkbox. The actual key value should be masked in the Bubble editor UI.

Expected result: API Connector shows 'SEMrush API' with a GET call named 'Get Domain Ranks'. The `key` parameter has the Private checkbox enabled. Note: Do NOT initialize the call yet — this comes after setting up the Toolbox parsing workflow.

3

Install Toolbox plugin and build the text parsing Backend Workflow

Go to Plugins tab → 'Add plugins' → search 'Toolbox' → Install 'Toolbox' by Bubble (free). This plugin adds a 'Server Script' action to Bubble workflows that runs JavaScript server-side, which you'll use to parse SEMrush's semicolon-delimited text. Now build the parsing workflow. In the Bubble editor, create a Backend Workflow named 'Fetch SEMrush Domain Data'. Add a text input parameter to this workflow named 'domain' (this is passed when the workflow is called from a page). Add the following actions to the workflow: Action 1: 'Plugins → SEMrush API - Get Domain Ranks'. Set the domain parameter to: This workflow's domain. This makes the API call and stores the result as Step 1's text response. Action 2: 'Toolbox - Server Script'. In the Script field, enter the JavaScript parsing code below. This script receives the SEMrush plain text, splits it into headers and values, and returns a structured JSON object. Set the 'Result type' to 'text' or 'object' depending on how you'll use the output. Action 3: 'Create a new DomainMetric' (your Bubble data type, created in the next step). Map the fields from the Server Script's output: organic_keywords = Step 2's result's Or, organic_traffic = Step 2's result's Ot, etc. To trigger this workflow from a Bubble page, add a 'Schedule API Workflow' action on a 'Refresh SEMrush Data' button, passing the domain input value as the workflow's domain parameter.

semrush-text-parser.js
1// Toolbox Server Script — parse SEMrush semicolon-delimited text
2// Action type: Server Script in Backend Workflow
3// Input: Step 1's body (the raw SEMrush API text response)
4
5var raw = properties.text_input; // the raw SEMrush response text
6var lines = raw.split('\n').filter(function(l) { return l.trim().length > 0; });
7
8if (lines.length < 2) {
9 // No data or error response
10 return { error: raw };
11}
12
13var headers = lines[0].split(';');
14var values = lines[1].split(';');
15
16var result = {};
17for (var i = 0; i < headers.length; i++) {
18 result[headers[i]] = values[i] || '';
19}
20
21return result;
22
23// Example output for domain_ranks:
24// { Or: "12345", Ot: "450000", Oc: "3.50", Ad: "200", At: "15000", Ac: "2.00" }

Pro tip: SEMrush may return 'ERROR 50 :: NOTHING FOUND' as a plain text response if the domain has no data in the selected database. Add a check in your Server Script: if the raw text starts with 'ERROR', return an error object and handle it gracefully in your workflow (e.g., skip creating a DomainMetric record).

Expected result: Backend Workflow 'Fetch SEMrush Domain Data' has three actions: the API call, the Server Script parser, and a database create action. Triggering the workflow manually with a test domain returns a DomainMetric record with numeric values populated.

4

Create the DomainMetric data type and cache results

Before running the Backend Workflow, create the Bubble data type that will store cached SEMrush results. Go to Data tab → Data types → 'Create a new type' → name it 'DomainMetric'. Add these fields: - `domain` (text) — the queried domain (bare format, e.g., 'example.com') - `organic_keywords` (number) — from SEMrush Or column - `organic_traffic` (number) — from SEMrush Ot column - `organic_cost` (number) — from SEMrush Oc column - `paid_keywords` (number) — from SEMrush Ad column - `paid_traffic` (number) — from SEMrush At column - `fetched_at` (date) — when this data was last retrieved - `database` (text) — the SEMrush geographic database used (e.g., 'us', 'uk') In the Backend Workflow's Action 3, map the Server Script output to these fields. Note that all SEMrush values come back as strings even when they're numbers — convert them using Bubble's ':converted to number' operator on each field. Add a cache check to avoid re-fetching within 24 hours. At the start of your Backend Workflow, add a conditional: if a DomainMetric already exists for this domain with fetched_at within the last 24 hours, stop the workflow (Only when: search for DomainMetrics where domain = this workflow's domain, fetched_at > Current date/time - 1 day → count = 0). Set Privacy rules: Data tab → Privacy → DomainMetric. SEMrush data is paid competitive intelligence. Restrict access to admin-role users or logged-in users only. Do not allow anonymous access through Bubble's Data API. WU note: each Backend Workflow run that calls SEMrush consumes both Bubble WU (API call, workflow steps, database write) and SEMrush API units. The 24-hour cache prevents both types of consumption from adding up on high-traffic dashboards.

domain-metric-data-type.txt
1// Bubble data type: DomainMetric
2// domain (text)
3// organic_keywords (number)
4// organic_traffic (number)
5// organic_cost (number)
6// paid_keywords (number)
7// paid_traffic (number)
8// fetched_at (date)
9// database (text)
10
11// Privacy Rule (Data tab → Privacy → DomainMetric):
12// Condition: Current User is logged in
13// Access: View all fields = YES
14
15// Cache check condition in Backend Workflow:
16// Only when: Do a search for DomainMetrics
17// constraint: domain = This workflow's domain
18// constraint: fetched_at > Current date/time - 1 day
19// :count is 0
20// (Skip the fetch if recent data exists)

Pro tip: When deduplicating cached records, check for an existing DomainMetric where domain = the input domain AND fetched_at is within the last 24 hours. If found, update the existing record's values and fetched_at rather than creating a second record for the same domain.

Expected result: DomainMetric data type has all fields defined. After running the Backend Workflow for a test domain, Data tab shows a DomainMetric record with numeric organic_traffic and organic_keywords values, and a fetched_at timestamp.

5

Build the competitive SEO intelligence dashboard

Create a new Bubble page called 'seo-dashboard'. This page displays SEMrush metrics for your domain and competitor domains side by side, reading from the cached DomainMetric data type. Add a Repeating Group with type 'DomainMetric'. Set the data source to 'Do a search for DomainMetrics', sorted by organic_traffic descending. In each row, display: - domain (text) - organic_keywords (formatted with commas as a number) - organic_traffic (formatted as a number with commas) - organic_cost (formatted as currency '$###,###') - paid_keywords (formatted with commas) - fetched_at (formatted as 'Last updated: MMM D, YYYY') Add a text Input element above the Repeating Group labeled 'Add domain to track'. Add a button 'Fetch SEMrush Data' with a workflow: trigger Backend Workflow 'Fetch SEMrush Domain Data' with domain = Input's value. Add validation: the Input value must not be empty and must not start with 'http' (bare domain only — strip protocol if users accidentally include it). For the bar chart comparison view, add a visual chart element. If your Bubble plan includes charts, create a bar or horizontal bar chart bound to the DomainMetric search with organic_traffic as the value axis and domain as the category axis. This gives an instant visual comparison of estimated organic traffic across tracked domains. RapidDev's team has helped agencies build Bubble-based SEO intelligence portals using SEMrush, Ahrefs, and Google Search Console in unified dashboards — if you need a multi-source competitive dashboard built, reach out at rapidevelopers.com/contact.

seo-dashboard-layout.txt
1// SEO Dashboard — Repeating Group layout
2
3// Repeating Group data source:
4// Search for DomainMetrics
5// Sort: organic_traffic descending
6// Columns: domain | organic_keywords | organic_traffic | organic_cost | fetched_at
7
8// 'Add Domain' input validation workflow:
9// Condition: Input's value is empty → show alert 'Please enter a domain'
10// Condition: Input's value contains 'http' → show alert 'Enter bare domain only (e.g. example.com)'
11// Otherwise: Schedule API Workflow 'Fetch SEMrush Domain Data'
12// with domain = Input's value
13
14// Number formatting examples in text elements:
15// organic_traffic: Current cell's DomainMetric's organic_traffic:formatted as ###,###
16// organic_cost: Current cell's DomainMetric's organic_cost:formatted as $###,###.##
17// fetched_at: Current cell's DomainMetric's fetched_at:formatted as 'MMM D, YYYY'

Pro tip: Add a 'Force Refresh' button that bypasses the 24-hour cache check and re-fetches SEMrush data immediately. This is useful when you've just published a new campaign and want to see updated metrics. Implement it by adding a workflow step that deletes the existing DomainMetric for the selected domain before triggering the fetch workflow.

Expected result: Dashboard page shows a Repeating Group comparing multiple domains' SEMrush organic traffic, keyword counts, and paid metrics. The 'Add domain' flow triggers a Backend Workflow that fetches SEMrush data, parses it, and adds a new row to the dashboard.

Common use cases

Competitive Domain SEO Dashboard

Pull domain-level organic traffic estimates, keyword rankings, and paid search spend for your domain and up to 3 competitor domains into a Bubble side-by-side comparison dashboard. Data is cached in Bubble's database and refreshed daily on demand. Color-code metrics where your domain outperforms or underperforms versus competitors.

Bubble Prompt

Build a Bubble dashboard comparing my domain against two competitors using SEMrush data: show estimated monthly organic traffic, number of ranking keywords, and ad spend for each. Refresh data with a button and show when data was last updated.

Copy this prompt to try it in Bubble

Keyword Position Tracker

Track how specific target keywords rank for your domain using SEMrush's phrase_this report type. Store weekly snapshots of keyword position, search volume, and CPC in a Bubble data type. Display position trend lines over time using Bubble's chart elements to show whether rankings are improving or declining.

Bubble Prompt

Create a Bubble keyword tracking page where admins enter a keyword and domain, then see the current SEMrush ranking position, search volume, CPC, and a 4-week position history stored in the database. Show a trend arrow (up/down) compared to last week's position.

Copy this prompt to try it in Bubble

Client SEO Reporting Portal

For agencies, build a white-label Bubble portal where clients can see their domain's SEMrush metrics without logging into SEMrush directly. Each client record stores their domain. An admin-triggered weekly refresh pulls the latest domain_ranks data for all clients and stores results. Client-facing pages show their own data with no access to others' reports.

Bubble Prompt

Build a Bubble client portal where each client sees their own SEMrush organic traffic estimate, keyword count, and top 10 ranking keywords. Admin users can refresh all client data from a single 'Update All Clients' button that runs a scheduled Backend Workflow.

Copy this prompt to try it in Bubble

Troubleshooting

API Connector Initialize call fails with 'There was an issue setting up your call' or shows a parsing error

Cause: SEMrush returns semicolon-delimited plain text, not JSON. Bubble's Initialize call attempts to parse responses as JSON and fails on SEMrush's text format. This is the most common first-step blocker for the SEMrush integration.

Solution: Do not use the Initialize call feature for SEMrush API calls. Instead, configure the API Connector call parameters manually without initializing. Use the Toolbox Server Script in a Backend Workflow to parse the raw text response — this is the correct architecture for non-JSON APIs. The API Connector call will still work for making requests even without initialization; you just won't have Bubble's auto-detected field types.

SEMrush returns 'ERROR 50 :: NOTHING FOUND' instead of data

Cause: The domain was entered with https:// prefix, www. prefix that doesn't match SEMrush's record, a trailing slash, or the domain genuinely has no data in the selected geographic database (database=us, uk, etc.).

Solution: Verify the domain format is bare: `example.com` not `https://www.example.com/`. In Bubble, strip the https:// prefix from user input using `:find & replace` with 'https://' replaced by '', and similarly for 'http://', 'www.', and trailing '/'. Also try switching the database parameter to a different country — some domains have data only in specific geographic SEMrush databases.

SEMrush API returns 'ERROR 120 :: You have run out of limits'

Cause: Monthly API unit limit for the SEMrush account has been exhausted. SEMrush API units are charged per call and per data row returned for certain report types. A domain_organic call with display_limit=200 consumes 200 units in a single request.

Solution: Reduce display_limit values for keyword-level report calls (set to 50 or less). Implement aggressive caching in Bubble — only re-fetch SEMrush data when the cached result is older than 24 hours. Check remaining API units in SEMrush Account Settings → API. Upgrade the SEMrush plan if the monthly unit allocation is consistently insufficient for your use case.

Toolbox Server Script returns undefined or throws an error when processing SEMrush response

Cause: The raw text being passed to the Server Script is not the SEMrush response body — it may be an error string, empty, or the wrong step's output is being referenced. Alternatively, the SEMrush response includes Windows-style line endings (\r\n) that split differently than Unix-style (\n).

Solution: In the Server Script, update the split to handle both line ending styles: replace `raw.split('\n')` with `raw.split(/\r?\n/)`. Also add a null check: if `!raw || raw.length === 0`, return an error object rather than letting the script crash. Check Bubble's Logs tab → Workflow logs to see the exact text value being passed to the Server Script as input.

typescript
1// Updated line splitting to handle Windows line endings:
2var lines = raw.split(/\r?\n/).filter(function(l) { return l.trim().length > 0; });

Best practices

  • Always pass the SEMrush API key as a Private URL parameter named `key` — never in a request body or in a visible (non-Private) URL parameter. Even though it's technically a query string parameter, the Private checkbox in Bubble's API Connector keeps it server-side.
  • Cache SEMrush results in a Bubble DomainMetric data type with a fetched_at timestamp. Only fetch fresh data when the cache is older than 24 hours. SEMrush data updates weekly for most metrics — fetching multiple times per day wastes API units without providing fresher data.
  • Use the display_limit parameter on all keyword-level report calls (domain_organic, phrase_this). For domain_ranks, there's only ever 1 row — but for keyword reports, each row consumes API units. A display_limit=50 limits a single domain_organic call to 50 unit consumption.
  • Enter domains in bare format (example.com) and strip protocols and trailing slashes from all user input before passing to the SEMrush API. Use Bubble's :find & replace operator to remove 'https://', 'http://', and trailing '/' from Input values.
  • Set Privacy rules on your DomainMetric data type to restrict access to admin users. SEMrush data represents paid intelligence about competitor domains — it should not be readable through Bubble's public Data API or accessible to non-admin users.
  • The Toolbox Server Script in a Backend Workflow is the recommended parsing approach for SEMrush text responses. Avoid trying to handle the parsing in client-side workflows or page-level expressions — server-side parsing is more reliable and keeps API results private.
  • For large datasets (multiple domains, multiple report types), stagger Backend Workflow scheduling using the 'delay' option rather than running all SEMrush calls simultaneously. SEMrush has per-second rate limits — sequential calls with brief delays are safer than concurrent calls that may trigger rate limiting.
  • Monitor your SEMrush API unit balance regularly in Account Settings → API. Build a low-unit warning into your Bubble admin dashboard by storing the unit balance response (available from the SEMrush API info endpoint) and alerting admin users when balance drops below a threshold.

Alternatives

Frequently asked questions

Can I use SEMrush API on Bubble's free plan?

Yes for the basic API Connector calls, but the Toolbox Server Script and Backend Workflows that handle text parsing and scheduled refreshes work best on a paid Bubble plan. More importantly, SEMrush itself requires a paid plan (Pro, Guru, or Business) to access the API — there is no API access on SEMrush's free tier.

Why does SEMrush return text instead of JSON? Is there a JSON mode?

SEMrush's API was designed before JSON became the universal standard for web APIs. Most report endpoints return semicolon-delimited text by default. Some newer SEMrush API endpoints do return JSON (the SEMrush Analytics API v3, for example), but the core domain and keyword report endpoints used for competitive intelligence remain text-based. The Toolbox Server Script parsing approach handles this consistently.

How many SEMrush API units does a domain_ranks call consume?

The domain_ranks report type consumes 1 API unit per call regardless of columns selected. Keyword-level reports like domain_organic consume units per row returned — a call with display_limit=100 consumes 100 units. For competitive dashboards tracking multiple domains, each domain_ranks refresh costs one unit per domain. Manage costs by caching results and setting appropriate display_limit values for any keyword-level calls.

Can Bubble handle SEMrush's geographic database parameter?

Yes. The database URL parameter selects the country: `us` for United States, `uk` for United Kingdom, `de` for Germany, `au` for Australia, and so on. In Bubble, make database a dynamic parameter or a dropdown selection. Store it alongside the domain in your DomainMetric data type so you know which country's data each cached record represents — especially important for multi-market agencies.

What is the domain_organic report and when should I use it instead of domain_ranks?

domain_ranks returns summary-level metrics for a domain (total organic traffic estimate, total keyword count) in a single row. domain_organic returns the actual keyword list — each keyword where the domain ranks, with its position, search volume, URL, and CPC. Use domain_ranks for dashboard summary cards. Use domain_organic when you need the keyword-level breakdown. Note that domain_organic costs one API unit per row (each keyword) — use display_limit=50 to keep costs predictable.

How do I handle the Server Script if SEMrush returns an error like 'ERROR 50 :: NOTHING FOUND'?

In your Toolbox Server Script, check whether the raw text starts with 'ERROR' before trying to parse it as a delimited response. If it does, return an error object: `{ error: raw }`. In the subsequent workflow action, add a condition: Only create a DomainMetric record if the Server Script's result does not contain an 'error' key. This prevents empty or error records from polluting your database.

RapidDev

Talk to an Expert

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

Book a free consultation

Integrations are where projects stall

We wire Bubble integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

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.