FlutterFlow's native version control only syncs with GitHub — there is no Bitbucket connector. You have two honest paths: mirror FlutterFlow's exported Dart code into a Bitbucket repository outside FlutterFlow, or use Bitbucket's Cloud REST API (v2.0) to read repo data and PR status inside a FlutterFlow app. Auth uses App Passwords or Access Tokens — never your account password — and tokens must be proxied through a Firebase Cloud Function or Supabase Edge Function for security.
| Fact | Value |
|---|---|
| Tool | Bitbucket |
| Category | DevOps & Tools |
| Method | FlutterFlow API Call |
| Difficulty | Intermediate |
| Time required | 45 minutes |
| Last updated | July 2026 |
Two Ways to Connect FlutterFlow and Bitbucket
When developers search for 'FlutterFlow Bitbucket', they usually want one of two things: to version-control their FlutterFlow project in Bitbucket, or to build an in-app dashboard that shows Bitbucket repo data. Both are possible — but neither works the way you might expect from GitHub's native integration, so it is worth understanding the difference before you start.
FlutterFlow's version control feature (under Settings & Integrations > GitHub) connects exclusively to GitHub. It creates a branch, pushes your FlutterFlow project's Dart code, and lets you roll back to previous versions — but only to a GitHub repository. There is no Bitbucket toggle, no GitLab option, and no Atlassian OAuth in FlutterFlow's settings panel. To get your FlutterFlow code into Bitbucket, you either export the Dart code and push it to Bitbucket outside FlutterFlow, or use a GitHub-to-Bitbucket mirror (a common DevOps pattern where you maintain both).
For reading Bitbucket data in a FlutterFlow app — for example, an internal DevOps dashboard that shows your team's open PRs or the latest Pipeline build status — you use the Bitbucket Cloud REST API at https://api.bitbucket.org/2.0/. Auth is with an App Password or Repository/Workspace Access Token (Bearer). Bitbucket deprecated basic username/password authentication; App Passwords are the modern equivalent. The free plan supports up to 5 users; Standard is approximately $3 per user per month; Premium is approximately $6 per user per month (verify current pricing at bitbucket.org). The API rate limit is approximately 1,000 requests per hour per user — sufficient for a polling dashboard but check current limits before building high-frequency polling.
Integration method
FlutterFlow has no native Bitbucket version control connector — its built-in GitHub sync panel only supports GitHub. To connect to Bitbucket, you either mirror FlutterFlow's exported Dart code into a Bitbucket repo manually, or you call the Bitbucket Cloud REST API (base URL: https://api.bitbucket.org/2.0/) from a FlutterFlow API Call group to display repo data, PR status, or Pipeline results inside an in-app dashboard. All authentication tokens must be proxied through a Firebase Cloud Function or Supabase Edge Function — embedding them in FlutterFlow's API Call headers ships them in the compiled Dart app.
Prerequisites
- A FlutterFlow project open in your browser
- A Bitbucket Cloud account with at least one workspace and repository
- A Bitbucket App Password (or Repository/Workspace Access Token) created with the required scopes
- A Firebase project (with Cloud Functions enabled) or a Supabase project (for the required token proxy)
- Basic familiarity with FlutterFlow's API Calls panel
Step-by-step guide
Understand the two Bitbucket paths — no native sync exists
Before spending time looking for a Bitbucket panel in FlutterFlow's settings, it is important to confirm: there is no Bitbucket option in FlutterFlow's version control. FlutterFlow's GitHub sync (Settings & Integrations > GitHub > Connect GitHub) connects exclusively to GitHub repositories — it is a GitHub OAuth flow. You will not find a Bitbucket section anywhere in FlutterFlow's settings UI. Given this, you have two distinct use cases to choose between: Path 1 — Code mirroring for version control: You want your FlutterFlow project's Dart code in a Bitbucket repository. The method is to connect FlutterFlow to GitHub (using its native GitHub sync), then mirror the GitHub repository to Bitbucket. GitHub-to-Bitbucket mirroring can be done by scheduling a mirror sync in Bitbucket (Repository Settings > Repository details > Mirroring) or using a Bitbucket Pipelines job that pulls from GitHub. FlutterFlow pushes to GitHub; the mirror keeps Bitbucket in sync automatically. Path 2 — In-app Bitbucket data: You want to display Bitbucket data (repos, PRs, pipeline status) inside a FlutterFlow app screen. For this, you use the Bitbucket Cloud REST API at https://api.bitbucket.org/2.0/ via FlutterFlow's API Calls panel, with an App Password or Access Token for authentication. This guide focuses on Path 2 (the REST API approach), which is the more technically interesting integration. If you only need mirroring, set up FlutterFlow's GitHub sync first, then configure the Bitbucket mirror from the Bitbucket side — no FlutterFlow-specific configuration is needed for the mirror.
Pro tip: If your company requires Bitbucket for compliance but your developers prefer GitHub's workflow, the GitHub-to-Bitbucket mirror approach gives you the best of both: FlutterFlow's GitHub integration stays intact and Bitbucket gets a continuous copy.
Expected result: You understand the two connection paths and have decided whether you need code mirroring, an in-app API dashboard, or both. For the API dashboard path, proceed to create credentials in the next step.
Create a Bitbucket App Password or Access Token with the right scopes
Bitbucket Cloud deprecated basic username/password authentication for API calls. Modern authentication uses App Passwords (tied to your Bitbucket user account) or Access Tokens (tied to a repository, workspace, or project). Do not use your real Bitbucket account password in any API Call or code — it will not work for API calls and is a serious security risk. To create an App Password, log into Bitbucket and go to your profile avatar (top-right) > Personal settings > App passwords > Create app password. Give it a descriptive name (e.g., 'FlutterFlow Dashboard'). Select the minimum scopes you need: for reading repositories, select 'Repositories: Read'; for reading pull requests, add 'Pull requests: Read'; for pipeline status, add 'Pipelines: Read'. Click Create and copy the generated password immediately — Bitbucket shows it only once. Alternatively, use a Repository Access Token (repository-scoped) or Workspace Access Token (workspace-scoped) from Repository Settings or Workspace Settings > Access tokens. Access Tokens are scoped to specific repositories or workspaces, which is safer than App Passwords (which cover your entire account). The token uses Bearer authentication in API calls: the Authorization header value is 'Bearer {token}' (for Access Tokens) or 'Basic {base64(username:appPassword)}' (for App Passwords). Do NOT put this token directly in FlutterFlow's API Call headers — it will be compiled into the Dart app and extractable by anyone who decompiles the APK. The next steps show how to proxy it through a backend function instead.
Pro tip: For App Passwords, use 'Basic' auth with a base64-encoded 'username:appPassword' string. For Access Tokens, use 'Bearer token' directly. These behave differently in the Authorization header — the Bitbucket API docs confirm which format each credential type requires.
Expected result: You have a Bitbucket App Password or Access Token copied and saved securely (a password manager). You know its scopes and which repositories or workspaces it can access.
Deploy a Firebase Cloud Function proxy to hold the Bitbucket token
The Bitbucket App Password or Access Token is a secret credential — embedding it in FlutterFlow's API Call headers means it ships in the compiled Dart app. Anyone who decompiles the APK (a trivial process) can extract and reuse the token. Instead, the token must live in a server-side function that your FlutterFlow app calls. The function holds the token in an environment variable, calls the Bitbucket API on behalf of your app, and returns the result. The easiest backend for FlutterFlow is Firebase Cloud Functions (if you already use Firebase) or a Supabase Edge Function (if you use Supabase). Below is an example Firebase Cloud Function (Node.js) that accepts a workspace and repo name from your FlutterFlow app and returns the list of open pull requests from Bitbucket. Deploy it to Firebase, then add its HTTPS URL as the API Call base URL in FlutterFlow. In the Firebase Console, go to Project settings > Service accounts > Generate new private key if you need Firebase Admin SDK — but for this proxy, you only need the Bitbucket token as an environment variable set via Firebase CLI or the Firebase Console (Functions > your function > Configuration > Runtime environment variables). The function never exposes the token to the client. Jenkins users often also need a backend proxy because Jenkins typically lives on a private network. The same proxy pattern applies: the Cloud Function sits in the public cloud and forwards requests to the private Jenkins host, keeping credentials server-side.
1// Firebase Cloud Function — Bitbucket API proxy2// Deploy via Firebase Console > Functions or Firebase CLI3// Set BITBUCKET_TOKEN as an environment variable in Firebase Console45const functions = require('firebase-functions');6const https = require('https');78exports.bitbucketProxy = functions.https.onRequest(async (req, res) => {9 // Allow CORS for FlutterFlow web preview10 res.set('Access-Control-Allow-Origin', '*');11 res.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');12 res.set('Access-Control-Allow-Headers', 'Content-Type');13 if (req.method === 'OPTIONS') {14 res.status(204).send('');15 return;16 }1718 const token = process.env.BITBUCKET_TOKEN; // Set in Firebase env config19 const workspace = req.query.workspace;20 const repo = req.query.repo;21 const endpoint = req.query.endpoint || 'pullrequests';2223 if (!workspace || !repo) {24 res.status(400).json({ error: 'workspace and repo are required' });25 return;26 }2728 const bitbucketUrl =29 `https://api.bitbucket.org/2.0/repositories/${workspace}/${repo}/${endpoint}?state=OPEN`;3031 try {32 const response = await fetch(bitbucketUrl, {33 headers: { Authorization: `Bearer ${token}` }34 });35 const data = await response.json();36 res.status(response.status).json(data);37 } catch (err) {38 res.status(500).json({ error: err.message });39 }40});Pro tip: Set your Bitbucket token as a Firebase environment variable using the Firebase Console (Functions > Runtime environment variables) rather than hardcoding it in the function — this way the token never appears in your source code or version control.
Expected result: Your Firebase Cloud Function is deployed and accessible at an HTTPS URL (e.g., https://us-central1-{project}.cloudfunctions.net/bitbucketProxy). Calling it with valid workspace and repo parameters returns Bitbucket PR data as JSON.
Create the FlutterFlow API Calls group pointing to your proxy
With your backend proxy running, open FlutterFlow and click API Calls in the left navigation panel. Click + Add > Create API Group. Name it 'Bitbucket Dashboard' and set the Base URL to your Firebase Cloud Function URL (e.g., https://us-central1-{project}.cloudfunctions.net/bitbucketProxy). You do not add the Bitbucket token here — it lives in the Cloud Function. Under Headers, add 'Content-Type: application/json'. Inside the group, click + Add API Call. Name it 'GetPullRequests'. Set Method to GET. Leave the Path empty (your Cloud Function is the endpoint). Under the Variables tab, add the query parameters your proxy accepts: add variable 'workspace' (String) and 'repo' (String). These map to the ?workspace= and ?repo= query params the Cloud Function reads. Click the Response & Test tab. In the test inputs, enter your actual workspace slug and repo slug. Click Test — if your Cloud Function is deployed correctly, you see a 200 response with a JSON body containing the pull request list from Bitbucket. The response structure is Bitbucket's standard paginated format: { "values": [...], "pagelen": 10, "size": 15, "next": "https://..." }. Click Generate JSON Paths on the response. FlutterFlow extracts path patterns like $.values, $.values[0].title, $.values[0].state, $.values[0].author.display_name, $.values[0].links.html.href. Create a response variable for each field you want to display — these become the bindings for your ListView and Text widgets.
1// FlutterFlow API Call configuration reference2{3 "group_name": "Bitbucket Dashboard",4 "base_url": "https://us-central1-{project}.cloudfunctions.net/bitbucketProxy",5 "headers": {6 "Content-Type": "application/json"7 },8 "calls": [9 {10 "name": "GetPullRequests",11 "method": "GET",12 "path": "",13 "variables": [14 { "name": "workspace", "type": "String" },15 { "name": "repo", "type": "String" }16 ],17 "json_paths": {18 "prList": "$.values",19 "prTitle": "$.values[0].title",20 "prState": "$.values[0].state",21 "prAuthor": "$.values[0].author.display_name",22 "nextPage": "$.next"23 }24 }25 ]26}Pro tip: Bitbucket's API returns paginated results with a 'next' field containing the full URL for the next page — not a page number. Plan your UI with a 'Load More' button that calls the API again with the next URL, rather than building traditional page-number pagination.
Expected result: The FlutterFlow API Calls panel shows the Bitbucket Dashboard group with the GetPullRequests call returning a 200 response with PR data in the test tab. JSON paths are extracted and ready to bind to widgets.
Handle Bitbucket API pagination in your FlutterFlow UI
The Bitbucket Cloud REST API paginates all list responses. Unlike some APIs that use page number parameters, Bitbucket uses cursor-based pagination: the response body contains a 'next' field with the complete URL for the next page of results. If there are no more pages, 'next' is absent from the response. For a FlutterFlow dashboard listing pull requests, you have two practical approaches: Simple approach (no load-more button): Modify your proxy Cloud Function to accept a 'pagelen' parameter and set it to the maximum allowed (Bitbucket allows up to 100 items per page). For most small teams, 100 items is enough that pagination never becomes relevant. In your proxy, append ?pagelen=100 to the Bitbucket API request URL. This covers the majority of real-world use cases without building pagination UI. Load-more approach (for large workspaces): Add a response variable for the 'next' field (JSON path: $.next). Store this URL in a FlutterFlow page state variable. Add a 'Load More' button to the bottom of your ListView. Wire the button to an Action Flow that calls GetPullRequests again, but this time modifies the proxy call to forward the 'next' cursor URL directly to Bitbucket. Append the new page's values to the existing list state variable, then update the stored 'next' URL (or clear it when it is absent, hiding the 'Load More' button). For Pipeline status, add a second API Call in the same group — 'GetPipelineStatus' — pointing to /repositories/{workspace}/{repo}/pipelines?sort=-created_on&pagelen=5 in your proxy. This returns the 5 most recent Pipeline runs with their state (PASSED, FAILED, IN_PROGRESS) and the commit that triggered each run.
Pro tip: Use FlutterFlow's App State (a global state variable) rather than page state to store the current Bitbucket 'next' cursor — this way the loaded PR list persists if the user navigates away and returns to the dashboard without triggering a full reload.
Expected result: Your FlutterFlow app displays Bitbucket pull requests in a ListView with PR title, author, and state. If you implemented load-more, a 'Load More' button appears when there are additional pages and disappears when the last page is loaded.
Display Bitbucket data in FlutterFlow widgets and test on device
With your API Call configured and tested, bind the response data to FlutterFlow widgets. Add a ListView widget to the page. Set its data source to a Backend Query using your GetPullRequests API Call — pass the workspace and repo values from page variables (which you can set as constants for an internal tool or let the user select from a dropdown). Inside the ListView, add a Card or Container for each PR. Inside the card, add Text widgets for the PR title (bind to $.values[i].title), PR author (bind to $.values[i].author.display_name), target branch (bind to $.values[i].destination.branch.name), and a status badge (bind to $.values[i].state — values are 'OPEN', 'MERGED', 'DECLINED', 'SUPERSEDED'). Add a color conditional on the state field: green for MERGED, red for DECLINED, blue for OPEN. For Pipeline status, add a separate section or tab. Use another Backend Query with your GetPipelineStatus API Call. Bind the result field ($.values[i].state.result.name — values are 'SUCCESSFUL', 'FAILED', 'STOPPED') to a status indicator widget. Test your app in FlutterFlow's Run mode (click Run in the top toolbar) — the API Calls fire from your browser and return real Bitbucket data. Then test on a physical device or install via TestFlight/internal track to confirm the proxy call works from a mobile app context. If you are building a web app, test in a browser build to confirm the Cloud Function's CORS headers allow requests from your FlutterFlow web app's domain. If you need help wiring up a more complex Bitbucket dashboard, RapidDev's team builds FlutterFlow API integrations like this every week — free scoping call at rapidevelopers.com/contact.
Pro tip: Use FlutterFlow's Conditional Visibility feature on the 'Load More' button: set it to only show when the page state variable holding the 'next' cursor is not empty. This automatically hides the button when you have reached the last page of Bitbucket results.
Expected result: Your FlutterFlow app shows a live Bitbucket dashboard with open pull requests displayed as cards with correct author, title, and state. The data refreshes on page load by calling the proxy, which calls the Bitbucket API.
Common use cases
Internal DevOps dashboard showing Bitbucket PR and Pipeline status
A development team uses Bitbucket for all their source code. They build a FlutterFlow internal app that shows the currently open pull requests for each repository, the build status of the latest Bitbucket Pipeline run, and a count of unresolved comments per PR. The FlutterFlow app calls the Bitbucket REST API through a backend proxy and displays the data in a card-based ListView.
Build a DevOps dashboard app showing open pull requests from our Bitbucket workspace 'acme-corp', including PR title, author avatar, target branch, and Pipeline build result (passed/failed/in progress) — displayed as cards sorted by most recently updated.
Copy this prompt to try it in FlutterFlow
FlutterFlow project version-controlled in Bitbucket via GitHub mirror
A team wants their FlutterFlow project backed up in their company Bitbucket instance for compliance reasons. They connect FlutterFlow to a GitHub repository using FlutterFlow's native GitHub sync, then set up a Bitbucket mirror repository that automatically pulls commits from GitHub. FlutterFlow pushes to GitHub; Bitbucket stays in sync automatically without any FlutterFlow-side configuration.
Set up version control for my FlutterFlow project: connect it to a GitHub repo using FlutterFlow's GitHub sync, then configure a Bitbucket mirror so all commits automatically appear in our company Bitbucket workspace for compliance archiving.
Copy this prompt to try it in FlutterFlow
Repository browser app using Bitbucket API
A FlutterFlow mobile app that lets team members browse Bitbucket repositories, view commit history, and check which branches have open PRs — without logging into the Bitbucket web UI. The app uses a backend proxy that holds the Workspace Access Token, calls the Bitbucket REST API, and returns filtered repository and PR data to FlutterFlow widgets.
Build a mobile app for our Bitbucket workspace that lists all repos, shows the last 10 commits per repo with author and message, and highlights any repo with an open PR awaiting review — pulling data from the Bitbucket Cloud REST API.
Copy this prompt to try it in FlutterFlow
Troubleshooting
401 Unauthorized when calling the Bitbucket API
Cause: The App Password or Access Token is incorrect, expired, or missing the required scopes — or password-based authentication is being used instead of an App Password.
Solution: Verify the token in the Bitbucket settings where you created it. Ensure you are using an App Password (not your account password) or a Repository/Workspace Access Token. Check that the scopes include 'Repositories: Read' and 'Pull requests: Read'. If using App Password, the Authorization header value must be 'Basic {base64(username:appPassword)}', not 'Bearer'.
XMLHttpRequest error when testing the API Call in FlutterFlow's web preview
Cause: CORS is blocking the browser from calling the Bitbucket API directly. FlutterFlow's web build runs in a browser, which enforces CORS. The Bitbucket API does not allow cross-origin requests from arbitrary browser origins.
Solution: This is exactly why the proxy step is required. Ensure your Firebase Cloud Function or Supabase Edge Function includes CORS headers (Access-Control-Allow-Origin: *) and that FlutterFlow's API Call group points to the proxy URL, not to api.bitbucket.org directly. The proxy handles the Bitbucket call server-side where CORS does not apply.
Bitbucket API only returns 10 results even though there are more PRs
Cause: Bitbucket paginates list responses with a default page length of 10. The remaining results are available via the 'next' cursor URL in the response body.
Solution: Add pagelen=100 as a query parameter in your proxy's Bitbucket API call to get up to 100 items per page. For workspaces with more than 100 open PRs, implement cursor-based pagination by reading the 'next' field from the response and calling that URL for subsequent pages.
FlutterFlow version control shows no Bitbucket option in the GitHub sync panel
Cause: FlutterFlow's version control is GitHub-only. The GitHub sync panel does not support Bitbucket, GitLab, or any other Git host.
Solution: Use a GitHub-to-Bitbucket mirror: connect FlutterFlow to a GitHub repository first (Settings & Integrations > GitHub), then configure Bitbucket's repository mirroring feature (Repository Settings > Mirroring) to pull from GitHub automatically. FlutterFlow pushes to GitHub; Bitbucket stays in sync.
Best practices
- Never put a Bitbucket App Password or Access Token in FlutterFlow's API Call headers or App State — compiled Dart apps ship those values to every device where they can be extracted by decompiling the APK.
- Use Repository or Workspace Access Tokens instead of App Passwords for better scope control — Access Tokens can be limited to specific repositories, minimizing damage if they are ever leaked.
- Add pagelen=100 to your Bitbucket API proxy calls to avoid truncating results at the default 10-item limit — 100 items per page covers most team-sized PR queues without pagination complexity.
- Implement CORS headers (Access-Control-Allow-Origin: *) in your Firebase Cloud Function or Supabase Edge Function — FlutterFlow's web builds send browser requests, and Bitbucket rejects cross-origin requests from arbitrary origins.
- For internal DevOps dashboards, use App State to persist the loaded PR list across page navigations so users do not wait for a full reload every time they return to the screen.
- Connect FlutterFlow to GitHub for version control first, then use Bitbucket's mirror feature to sync to Bitbucket — this keeps FlutterFlow's native GitHub integration intact while satisfying Bitbucket compliance requirements.
- Test API Calls in FlutterFlow's Response & Test tab before building widgets — this runs from FlutterFlow's servers (not the browser) and confirms the proxy is reachable and returning correct data.
Alternatives
GitHub has a native FlutterFlow version control connector (Settings & Integrations > GitHub) — the simplest choice if version control is your goal, with no proxy needed for public repo data.
GitLab also lacks a native FlutterFlow connector but offers a similar REST API pattern with Personal Access Tokens — useful if your team is already on GitLab's CI/CD pipelines.
Jenkins integrates with FlutterFlow via the same REST API + proxy pattern, but focuses on CI build triggering and status polling rather than repository and PR management.
Frequently asked questions
Does FlutterFlow support Bitbucket for version control?
No — FlutterFlow's version control feature (Settings & Integrations > GitHub) connects exclusively to GitHub. There is no Bitbucket or GitLab option. To back up your FlutterFlow project in Bitbucket, connect FlutterFlow to GitHub first, then use Bitbucket's repository mirroring feature to automatically sync from GitHub.
Can I put my Bitbucket App Password in a FlutterFlow App State variable?
No. Any value stored in FlutterFlow's App State, Dart constants, or API Call headers is compiled into the app binary. An App Password stored this way is extractable by anyone who decompiles the APK or IPA — it must live in a Firebase Cloud Function or Supabase Edge Function environment variable that runs server-side.
What is the difference between a Bitbucket App Password and an Access Token?
App Passwords are tied to your personal Bitbucket account and grant the permissions you select across all workspaces your account belongs to. Repository, Workspace, and Project Access Tokens are scoped specifically to that resource — they do not grant access to your entire account. For FlutterFlow integrations, Repository or Workspace Access Tokens are more secure because a leaked token only exposes the scoped resource, not your whole account.
Why does my Bitbucket API call work in FlutterFlow's Test tab but fail in the web preview?
FlutterFlow's Test tab runs API calls from FlutterFlow's own servers (not from the browser), so CORS is not enforced. When the same call runs in a web preview, the browser blocks cross-origin requests to api.bitbucket.org because Bitbucket does not send permissive CORS headers. The fix is to route the call through your Firebase Cloud Function proxy, which adds the necessary CORS headers.
How do I get more than 10 pull requests from the Bitbucket API?
Bitbucket paginates list responses with a default of 10 items. Add the pagelen query parameter (up to pagelen=100) to your API call to increase the page size. For workspaces with more than 100 open PRs, read the 'next' field in the response body — it contains the full URL for the next page — and call it to retrieve subsequent pages.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation