# Ahrefs

- Tool: FlutterFlow
- Difficulty: Intermediate
- Time required: 45 minutes
- Last updated: July 2026

## TL;DR

Connect FlutterFlow to Ahrefs by creating a FlutterFlow API Call group with base URL https://api.ahrefs.com/v3 and a Bearer token header, then call site-explorer endpoints for Domain Rating and backlinks. Because the token is secret, route it through a Firebase Cloud Function proxy — never put it directly in the app. Cache responses in App State to avoid burning expensive API units.

## Build a Read-Only SEO Dashboard with Ahrefs and FlutterFlow

Ahrefs is one of the most comprehensive SEO toolsets in the industry, offering a REST API (v3) that surfaces Domain Rating, backlink counts, referring domains, keyword rankings, and much more. Access to the API is gated to Enterprise-tier Ahrefs plans, and every endpoint call costs a quantity of 'units' from your monthly quota — so the design of your FlutterFlow app has direct cost implications. Build it to fetch once and cache, not to re-query on every widget rebuild.

In FlutterFlow, Ahrefs is a pure API Call integration. You create an API Group with the base URL https://api.ahrefs.com/v3, attach a shared Authorization header containing your Bearer token, and then define separate API Calls for each endpoint you need — domain rating, backlinks, referring domains. Each call accepts query variables (target domain, date range) that the user supplies through your app's UI. FlutterFlow's JSON Path tool then extracts the fields you care about and binds them to text widgets or ListViews.

The critical constraint is security: Ahrefs tokens are high-value secrets that grant access to a paid Enterprise account. FlutterFlow compiles to native Dart code that runs on the user's device, and any token placed in an API Call header is embedded in the app bundle — extractable with standard reverse-engineering tools. The safe pattern is a Firebase Cloud Function (or Supabase Edge Function) that holds the token in its environment variables, proxies requests to Ahrefs, and returns the response. FlutterFlow then calls your Cloud Function URL instead of calling Ahrefs directly. This pattern also solves CORS for web builds, since browsers block cross-origin requests to api.ahrefs.com from a FlutterFlow web app.

## Before you start

- An active Ahrefs Enterprise subscription with API access enabled (API access is not available on Lite or Standard plans)
- Your Ahrefs API v3 Bearer token from the Ahrefs account settings under API
- A FlutterFlow project (free or paid) with at least one page to display SEO data
- A Firebase project (for the Cloud Function proxy) or a Supabase project (for the Edge Function proxy)
- Basic familiarity with FlutterFlow's API Calls panel and how to bind data to widgets

## Step-by-step guide

### 1. Set up the Firebase Cloud Function proxy to hold your Bearer token

Because an Ahrefs Bearer token is a paid Enterprise secret, it must never travel inside your compiled Flutter app. The right architecture is a Firebase Cloud Function that stores the token as an environment variable and forwards requests to Ahrefs on behalf of your app.

In the Firebase console, navigate to Functions and deploy a new HTTP function. The function receives a query parameter (target domain) from FlutterFlow, attaches your Bearer token from process.env.AHREFS_TOKEN, calls the relevant Ahrefs v3 endpoint, and returns the JSON response. Set the environment variable in the Firebase CLI: firebase functions:config:set ahrefs.token='YOUR_TOKEN_HERE'.

Once deployed, Firebase gives you a Cloud Function URL in the format https://us-central1-YOUR_PROJECT.cloudfunctions.net/ahrefsProxy. This is the URL you will use inside FlutterFlow — FlutterFlow calls your function, never Ahrefs directly. This single step solves both the secret-key exposure problem and the CORS issue for web builds, since your Cloud Function can set the correct CORS headers and return clean JSON.

If you prefer Supabase, the equivalent is a Supabase Edge Function (Deno): set the AHREFS_TOKEN in the Supabase dashboard under Settings → Edge Functions → Secrets, then deploy a function that reads Deno.env.get('AHREFS_TOKEN') and proxies the request. Either approach works; Firebase is used in the examples below.

```
// Firebase Cloud Function proxy (functions/index.js)
const functions = require('firebase-functions');
const axios = require('axios');

exports.ahrefsProxy = functions.https.onRequest(async (req, res) => {
  // Allow FlutterFlow web builds (CORS)
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Methods', 'GET, OPTIONS');
  if (req.method === 'OPTIONS') { res.status(204).send(''); return; }

  const token = process.env.AHREFS_TOKEN;
  const { target, endpoint, date_from, date_to, limit } = req.query;

  if (!target || !endpoint) {
    return res.status(400).json({ error: 'target and endpoint are required' });
  }

  const params = { target };
  if (date_from) params.date_from = date_from;
  if (date_to)   params.date_to = date_to;
  if (limit)     params.limit = limit;

  try {
    const response = await axios.get(
      `https://api.ahrefs.com/v3/${endpoint}`,
      {
        params,
        headers: { Authorization: `Bearer ${token}` }
      }
    );
    res.json(response.data);
  } catch (err) {
    const status = err.response?.status || 500;
    res.status(status).json({ error: err.message });
  }
});
```

**Expected result:** Your Cloud Function is live at a Firebase URL and returns Ahrefs JSON when you hit it directly in a browser with ?target=example.com&endpoint=site-explorer/domain-rating.

### 2. Create the Ahrefs API Group in FlutterFlow

Now that your proxy is live, you will create an API Group in FlutterFlow that points to your Cloud Function URL instead of directly to api.ahrefs.com. The API Group acts as a reusable connection object — everything you configure here (base URL, shared headers) is inherited by every API Call you add inside it.

In FlutterFlow, click API Calls in the left navigation panel. Then click + Add in the top-right of the panel and choose Create API Group. Name it Ahrefs (or AhrefsProxy if you want to be explicit). For the Base URL, paste your Cloud Function URL: https://us-central1-YOUR_PROJECT.cloudfunctions.net/ahrefsProxy.

Since your proxy is your own Firebase function, you do not need an Authorization header at the FlutterFlow level — the token lives inside the function. If you want to add lightweight protection to your proxy (so only your app can call it), you can add a custom header like X-App-Secret with a random string that you check in the function, but this is optional for an internal tool.

Save the API Group. You should see it listed under API Calls in the left nav, ready to receive individual endpoint definitions.

**Expected result:** The Ahrefs API Group appears in the left nav API Calls panel with your Cloud Function URL as its base. No API Calls are inside it yet.

### 3. Add API Calls for domain-rating and backlinks endpoints

Inside the Ahrefs API Group, you will create individual API Calls for each Ahrefs report you want to display. Each call is a GET request to your proxy, which forwards it to the appropriate Ahrefs v3 endpoint.

Click the + icon inside the Ahrefs API Group and select Create API Call. Name the first call Get Domain Rating. Set the HTTP Method to GET. In the URL field (which is relative to the group's base URL), leave it blank or type / — since your proxy accepts the endpoint as a query parameter rather than a path. Then go to the Variables tab and add the following query parameters:
  - target (String, required) — the domain to look up, e.g. example.com
  - endpoint (String, required) — hardcode or default to site-explorer/domain-rating
  - date_from (String, optional) — start of the date range, e.g. 2025-01-01

In the URL field, reference them as: /?target=[target]&endpoint=[endpoint]&date_from=[date_from].

Switch to the Response & Test tab. Enter a sample target domain in the test fields and click Test API Call. If your proxy is deployed and the Ahrefs account has API access, you will get a JSON response back. Click Generate JSON Paths. FlutterFlow will parse the response and create extractors for each field. Look for $.domain.domain_rating and save it — you will bind this to a Text widget later.

Repeat the process to add a second API Call named Get Backlinks, using endpoint=site-explorer/backlinks. Add a limit variable (default: 50) to cap the number of results returned per request and avoid burning too many units in one call.

```
// Sample API Call JSON configuration (for reference — configured in FlutterFlow UI)
{
  "group": "Ahrefs",
  "name": "Get Domain Rating",
  "method": "GET",
  "url": "/?target={{target}}&endpoint=site-explorer/domain-rating&date_from={{date_from}}",
  "headers": {},
  "variables": [
    { "name": "target",     "type": "String", "required": true  },
    { "name": "date_from", "type": "String", "required": false }
  ],
  "json_paths": [
    { "name": "domainRating", "path": "$.domain.domain_rating" },
    { "name": "ahrefs_rank",  "path": "$.domain.ahrefs_rank"  }
  ]
}
```

**Expected result:** Two API Calls — Get Domain Rating and Get Backlinks — appear inside the Ahrefs group. The Response & Test tab shows real data when you run a test.

### 4. Create a Data Type and store results in App State

Ahrefs charges API units per call, so re-fetching on every widget rebuild would silently drain your quota. The solution is to store responses in App State (FlutterFlow's global in-memory storage) after the first successful call, and only refresh when the user explicitly taps a Refresh button or pull-to-refresh.

First, define a custom Data Type to hold the parsed response. Go to the Data Types section (left nav → Data Types) and create a new type called AhrefsMetrics with fields: domainRating (double), ahrefsRank (int), backlinksTotal (int), refdomains (int), and lastFetched (String for the timestamp).

Next, go to App State (left nav → App State) and create a state variable called seoMetrics with the type AhrefsMetrics. This variable holds the last-fetched result across screens without re-calling the API.

Now wire the API Call to update this state. On your search screen, add an Action to the Search button: Backend/API Call → choose Ahrefs → Get Domain Rating. In the Action outputs, map the JSON Path results to the corresponding fields of the AhrefsMetrics Data Type, then add an Update App State action to write the populated Data Type into seoMetrics. The Text widgets on the results screen bind to AppState.seoMetrics.domainRating instead of directly to the API Call response, which means they always show the cached value instantly and only refresh when the user triggers a new search.

**Expected result:** App State has a seoMetrics variable of type AhrefsMetrics. Tapping Search triggers the API Call, writes results to App State, and all bound widgets update immediately.

### 5. Build the dashboard UI and bind data to widgets

With the API Group, API Calls, Data Type, and App State all configured, you can now build the visible part of the app — a clean dashboard showing Domain Rating, backlinks, and referring domains.

On your main SEO screen, add a TextField widget for the user to type a domain (e.g. 'example.com'). Below it, add a Button labeled Search. In the Button's Actions panel, add the sequence: first, set a loading state variable (isLoading = true) to show a progress indicator; second, call the Ahrefs Get Domain Rating API Call with the TextField value as the target variable; third, on the Call's success callback, update App State seoMetrics with the returned values and set isLoading = false; on error, show a Snackbar with the error message.

Below the TextField and Button, add a Column with Card widgets for each metric. Each Card contains a Text widget bound to AppState.seoMetrics.domainRating (or backlinksTotal, refdomains). Use conditional visibility so the cards are only visible when seoMetrics.domainRating is not null/zero.

For the backlinks list, add a ListView below the summary cards and set its data source to the Get Backlinks API Call. Add a pull-to-refresh widget (RefreshIndicator in Custom Code, or FlutterFlow's built-in Refresh widget) so users can manually trigger a new API call when they want updated data rather than getting a fresh call on every screen load.

**Expected result:** The dashboard screen shows a domain input field, a Search button, and metric cards that populate with Domain Rating and backlink count after the user searches. The ListView shows individual backlinks on demand.

### 6. Test on device and verify unit consumption

FlutterFlow's in-browser Run mode will test your proxy calls fine (since CORS is handled server-side in the Cloud Function), but you should also run a device test to confirm the full app flow works end-to-end on mobile.

Click Test Mode (or Run mode) in FlutterFlow and type a domain into the search field. Open your Cloud Function logs in the Firebase console and confirm that each tap of Search fires exactly one request to your function, which in turn makes one request to Ahrefs. Verify that subsequent opens of the same screen use the cached App State value instead of making another API call.

In the Ahrefs dashboard under your account → API, check the units consumed during testing. You should see a very small unit count (one or two calls) rather than dozens, confirming your caching strategy is working. If you see many calls, trace back to find where a widget is triggering a rebuild that re-calls the API, and move that API Call into the button action instead of a Page Load trigger.

For mobile builds, use FlutterFlow's Download as Code or APK export and test on a physical device or emulator. The API calls will behave identically since they go to your Firebase URL over HTTPS, which works on all platforms without any platform-specific permissions.

**Expected result:** The app fetches Ahrefs data on button tap, displays Domain Rating and backlink metrics correctly, and does not re-call the API on screen revisits. Firebase logs show only the expected number of function invocations.

## Best practices

- Never place the Ahrefs Bearer token in a FlutterFlow API Call header — always proxy through a Firebase Cloud Function or Supabase Edge Function where the token is an environment variable.
- Cache all API responses in App State with a timestamp, and re-fetch only on explicit user action (button tap or pull-to-refresh) to conserve your monthly unit quota.
- Set a reasonable limit parameter on backlinks and referring-domains endpoints (e.g. limit=50) to control units consumed per request.
- Display a 'last updated' timestamp next to metrics so users know the data age and understand why it doesn't update automatically.
- Add a loading indicator (CircularProgressIndicator) and disable the Search button while an API call is in flight to prevent duplicate requests from impatient taps.
- Log every Cloud Function invocation with the target domain and response status so you can audit unit usage and catch unexpected spikes.
- Check the Ahrefs API changelog periodically — v3 endpoint paths and response schemas can change, and a silent 404 may break your JSON Path extractors without an obvious error in the UI.
- For multi-user apps, scope the App State cache per user by including the user's ID in the state key, so one user's search doesn't overwrite another user's cached results.

## Use cases

### Internal SEO metrics dashboard app

Build a mobile app for your marketing team that shows Domain Rating, referring domain count, and new vs lost backlinks for any domain. The team enters a domain in a TextField, taps Search, and sees a clean dashboard card with the current metrics fetched live from Ahrefs. Responses are cached in App State so the next open skips the API call and saves units.

Prompt example:

```
An internal SEO dashboard app where the user types a domain name, hits Search, and sees Domain Rating, total backlinks, and referring domains pulled from Ahrefs in a card layout.
```

### Client SEO reporting companion app

An agency builds a white-label companion app for clients that displays their site's Ahrefs metrics in a branded interface. Each client logs in, sees their domain's Domain Rating trend over the past 30 days, and can tap into a backlink list. The app calls a Cloud Function proxy that authenticates with the shared Ahrefs Enterprise token, keeping it off the client device.

Prompt example:

```
A client-facing SEO reporting app that shows Domain Rating history as a line chart and lists the top 20 backlinks for the client's domain, refreshed once daily and cached locally.
```

### Competitor backlink gap analysis tool

Build a side-by-side comparison screen where a user enters their domain and a competitor domain, then sees both Domain Ratings and referring domain counts fetched from Ahrefs. A simple score card highlights the gap, giving an instant read on backlink authority relative to a chosen rival.

Prompt example:

```
A competitor analysis app where a user types two domains and sees their Domain Rating and referring-domain count side by side, with a gap indicator, all from Ahrefs API data.
```

## Troubleshooting

### 403 Forbidden from Ahrefs API — 'You do not have access to this API'

Cause: The Ahrefs API v3 is only available on Enterprise plans. Lite and Standard subscribers get a 403 on all /v3 endpoints regardless of a valid token.

Solution: Confirm your Ahrefs account plan includes API access. Log into your Ahrefs account and navigate to Settings → Subscription. If you see API listed, also verify the Bearer token is still active (tokens can be rotated in API settings). If your plan does not include API, the integration is not available without upgrading.

### XMLHttpRequest error in FlutterFlow Run mode — API Call returns nothing

Cause: This is a CORS error. When running in FlutterFlow's browser-based Run mode, the app makes cross-origin requests. api.ahrefs.com blocks browser origins. If you are calling Ahrefs directly (without the proxy), all web-mode requests will fail silently with this error.

Solution: Ensure you are calling your Firebase Cloud Function URL, not api.ahrefs.com directly. The Cloud Function sets Access-Control-Allow-Origin: * in its response headers, so browser-based Run mode requests succeed. Check the URL in your API Group's base URL field and confirm it points to your Cloud Function.

### API units draining unexpectedly fast — quota nearly exhausted after light testing

Cause: One or more widgets are triggering the API Call on every rebuild (e.g. an API Call set as the data source of a widget that rebuilds on scroll or on state changes), rather than only on explicit user action.

Solution: Move your Ahrefs API Calls out of widget data sources and into button Actions only. Store results in App State and bind widgets to App State variables. Add a 'last fetched' timestamp and prevent re-fetch if data is less than N minutes old. Check each widget's action trigger and make sure no API Call fires on Page Load unless it is the first load with no cached data.

### 401 Unauthorized — 'Invalid token' even though the Bearer token looks correct

Cause: The token may have been rotated in the Ahrefs dashboard, or a space or newline was accidentally included when copying the token into the Cloud Function environment variable.

Solution: Go to your Ahrefs account API settings and generate a fresh token. Update the AHREFS_TOKEN environment variable in the Firebase Functions config (firebase functions:config:set ahrefs.token='NEW_TOKEN') and redeploy the function. Confirm no leading/trailing whitespace. Test by calling the Cloud Function URL directly in a browser before testing from FlutterFlow.

## Frequently asked questions

### Does FlutterFlow have a native Ahrefs integration?

No. Ahrefs is not in FlutterFlow's list of native integrations (which is limited to Firebase, Supabase, RevenueCat, Stripe, Maps, AdMob, and OneSignal). You connect to Ahrefs using FlutterFlow's API Calls panel with a custom API Group, following the steps in this guide.

### Can I put the Ahrefs Bearer token directly in the FlutterFlow API Call header?

Technically you can configure it there, but you should not. FlutterFlow compiles to native Flutter code that runs on the user's device. Any value in an API Call header is embedded in the app bundle and can be extracted by someone who decompiles your APK or IPA. Since an Ahrefs Enterprise API token is a high-value credential, it must live in a server-side environment variable inside a Firebase Cloud Function or Supabase Edge Function, never in the client.

### What Ahrefs plan do I need to access the API?

Ahrefs API v3 access requires an Enterprise plan, which is sold separately from standard Lite/Standard/Advanced subscriptions. If you are on a non-Enterprise plan, all API requests will return 403 Forbidden. Check current pricing and API unit costs directly on the Ahrefs website, as the unit cost per endpoint call varies and changes periodically.

### Will the integration work in FlutterFlow's web Run mode?

Yes, if you use the Cloud Function proxy. Direct calls from the browser to api.ahrefs.com fail due to CORS restrictions. The Cloud Function sets permissive CORS headers and returns clean JSON, so both web and mobile builds work identically through the proxy.

### How do I avoid draining my Ahrefs API units?

The most important safeguard is to never trigger an API Call from a widget data source that rebuilds automatically (on scroll, on state change, etc.). Instead, fire calls only from a user-initiated button tap, store results in App State, and bind widgets to the cached state. Add a timestamp and a minimum refresh interval so the app skips re-fetching if the data is recent enough.

---

Source: https://www.rapidevelopers.com/flutterflow-integrations/ahrefs
© RapidDev — https://www.rapidevelopers.com/flutterflow-integrations/ahrefs
