Connect FlutterFlow to Microsoft Azure by configuring separate API Call groups for each Azure service you need — Azure Functions as your secure backend gateway, Blob Storage via server-issued SAS URLs, and Cosmos DB through its REST API. There is no single Azure connector in FlutterFlow; each service becomes its own API Group with the appropriate auth header. Azure AD OAuth2 tokens and account keys must stay in your Azure Function config, never in FlutterFlow.
| Fact | Value |
|---|---|
| Tool | Microsoft Azure |
| Category | Database & Backend |
| Method | FlutterFlow API Call |
| Difficulty | Intermediate |
| Time required | 45 minutes |
| Last updated | July 2026 |
Using Microsoft Azure as the Backend for Your FlutterFlow App
Microsoft Azure is an umbrella platform — there is no single 'Azure connector' in FlutterFlow. When founders ask 'how do I connect FlutterFlow to Azure,' they usually mean one of three things: calling custom backend logic (Azure Functions), storing and retrieving files (Blob Storage), or reading and writing structured data (Cosmos DB). Each of these becomes a separate API Call group in FlutterFlow, each with its own base URL and auth header.
The most important architectural decision is where to put your credentials. Azure AD OAuth2 client secrets, storage account keys, and Cosmos DB resource keys are all secrets — they must live in your Azure Function's application settings, not in FlutterFlow. A Flutter app compiles to client-side code that runs on the user's device, which means any credential stored in a FlutterFlow variable or Dart file can be extracted. The safe pattern: your Azure Function acts as the gateway, authenticates to Azure on your behalf, and returns only the data your app needs.
On the pricing side, Azure Functions' Consumption plan includes 1 million free executions per month — more than enough to prototype and grow a small production app. Blob Storage starts at roughly $0.018 per GB per month (check current Azure pricing for your region). Cosmos DB has a free tier of 400 RU/s and 5 GB of storage. Setting up each service takes about 15 minutes of Azure Portal work before you configure the FlutterFlow side.
Integration method
FlutterFlow calls Azure services through separate API Call groups — one per service. Azure Functions acts as your secure backend gateway, handling Azure AD authentication and business logic, while Blob Storage is reached via short-lived SAS URLs that your Function generates. Cosmos DB is accessed through its SQL REST API, fronted by the same Function layer. All secrets and OAuth tokens stay on Azure, never in your FlutterFlow project.
Prerequisites
- A FlutterFlow project created and opened in the browser
- An Azure account (free tier works for prototyping — sign up at portal.azure.com)
- An Azure Function App deployed with an HTTP trigger endpoint
- Basic familiarity with FlutterFlow's API Calls panel
- Your Azure Function URL and any required API keys or bearer tokens from your Function's auth setup
Step-by-step guide
Create an Azure Function HTTP endpoint as your backend gateway
Before touching FlutterFlow, you need a publicly reachable HTTPS endpoint. In the Azure Portal, navigate to Function Apps → Create and choose the Consumption (Serverless) plan with Node.js or Python runtime. Once the Function App is provisioned, go to Functions → Create → HTTP trigger and set the Authorization level to 'Function' (which requires an API key in the request) or 'Anonymous' (if you plan to validate tokens yourself). Write the function body: it should accept a JSON request from FlutterFlow, authenticate to downstream Azure services using credentials stored in the Function's Configuration → Application Settings — never in the source code — and return a clean JSON response. For Cosmos DB reads, use the Cosmos DB client library in your Function; for Blob operations, use the Azure Storage SDK. Enable CORS on the Function App itself: in the Azure Portal, go to the Function App → API → CORS and add your FlutterFlow published domain (e.g. https://yourapp.flutterflow.app) and also https://app.flutterflow.io for web preview. Without this, FlutterFlow's web build will receive CORS errors when testing in the browser.
1// Azure Function (Node.js) — HTTP trigger example2const { CosmosClient } = require('@azure/cosmos');34module.exports = async function (context, req) {5 // Credentials come from Application Settings, never hardcoded6 const client = new CosmosClient(process.env.COSMOS_CONNECTION_STRING);7 const container = client.database('mydb').container('items');89 if (req.method === 'GET') {10 const { resources: items } = await container.items.readAll().fetchAll();11 context.res = { body: { items } };12 } else if (req.method === 'POST') {13 const newItem = req.body;14 const { resource: created } = await container.items.create(newItem);15 context.res = { status: 201, body: created };16 }17};Pro tip: Store COSMOS_CONNECTION_STRING, BLOB_ACCOUNT_KEY, and any third-party keys in the Function App's Configuration → Application Settings — not in source code.
Expected result: Your Azure Function is live at https://{app-name}.azurewebsites.net/api/{function-name} and returns JSON when tested in a browser or Postman.
Register an Azure AD app and configure Function authentication
If your Azure Function needs to authenticate users or access other Azure services using OAuth2 (for example, reading from Azure Storage or Graph API on behalf of users), you need to register an app in Azure Active Directory. Go to Azure Portal → Azure Active Directory → App registrations → New registration. Name it (e.g. 'FlutterFlow Gateway'), set the redirect URI for web if needed, then note the Application (client) ID. Under Certificates & secrets, create a new client secret and immediately copy the value — Azure only shows it once. Back in your Function App's Configuration → Application Settings, add these values as environment variables (CLIENT_ID, CLIENT_SECRET, TENANT_ID). Your Function then uses these to mint OAuth2 bearer tokens via the client credentials flow when talking to other Azure services. FlutterFlow never sees these credentials: it only sends an app-level identifier (e.g., a user ID from your own auth system) to the Function, which handles the AAD token exchange entirely server-side. Azure AD tokens expire after approximately one hour; implement token refresh inside the Function, not on the client.
Pro tip: If you only need to call your own Azure Function and not other Azure services, you can skip AAD entirely and use a simple API key in the Function's host-key settings. AAD is needed when the Function itself calls the Azure Management API, Graph API, or Azure Storage on behalf of users.
Expected result: Your Azure AD app registration is complete. The Function App's Application Settings now contain CLIENT_ID, CLIENT_SECRET, and TENANT_ID — ready to use inside the Function when calling other Azure services.
Add API Call groups in FlutterFlow for each Azure service
Now configure FlutterFlow to talk to your Azure endpoints. Click API Calls in the left navigation panel, then click the + Add button and choose Create API Group. Give this group a descriptive name, such as 'Azure Functions'. Set the Base URL to your Function App's base URL: https://{app-name}.azurewebsites.net/api. Under Headers, add a header named 'x-functions-key' and set its value to your Function's host key (found in the Azure Portal under your Function → Function Keys → default). This is a publishable-style key that authorizes requests to your Function — it is not the same as your account key or client secret, so it is acceptable to store it in an App Values constant in FlutterFlow. Next, inside the API Group, click + Add API Call. Set the Method to GET, name it 'GetItems', and set the path to /getItems (or whatever your Function endpoint is named). Click the Variables tab and add any query parameters your Function expects (e.g., userId). Switch to the Response & Test tab, paste a sample JSON response from your Function, and click Generate JSON Paths — FlutterFlow will auto-generate the path expressions you'll use to bind data to widgets. Repeat this process to create additional API Calls within the same group: one for POST (creating records), one for PUT (updating), one for DELETE. For Cosmos DB and Blob operations, create a second API Group named 'Azure Blob' with the base URL https://{account}.blob.core.windows.net, and add calls as needed.
1// Sample API Call config (JSON representation)2{3 "group_name": "Azure Functions",4 "base_url": "https://myapp.azurewebsites.net/api",5 "headers": {6 "x-functions-key": "{{functionKey}}",7 "Content-Type": "application/json"8 },9 "calls": [10 {11 "name": "GetItems",12 "method": "GET",13 "path": "/getItems",14 "variables": ["userId"]15 },16 {17 "name": "CreateItem",18 "method": "POST",19 "path": "/createItem",20 "body": { "name": "{{itemName}}", "quantity": "{{qty}}" }21 }22 ]23}Pro tip: Use FlutterFlow's App Values (Settings → App Values) to store the Function host key as a constant — it keeps the value out of plaintext in individual widget bindings.
Expected result: Your API Groups appear in the left-nav API Calls panel. The Test tab on each API Call returns a 200 response with the expected JSON payload from Azure.
Wire a Blob Storage upload flow using a server-issued SAS URL
File uploads to Azure Blob Storage from FlutterFlow require a two-step process because the Blob Storage account key must never leave your backend. First, FlutterFlow calls an Azure Function endpoint (e.g., GET /generateSasUrl?filename=photo.jpg) that generates a short-lived Shared Access Signature URL using the Blob Storage SDK with the account key stored securely in the Function's Application Settings. The Function returns a JSON response containing the SAS URL, which is valid for a configurable period (typically 5–15 minutes). In FlutterFlow, set up this flow in the Action Flow Editor: start with a widget (e.g., an image picker button) → Actions panel → + Add Action → choose 'Upload Photo/Video' to get the file path into a local state variable. Then add a second action: API Call → your 'GenerateSasUrl' call, storing the returned SAS URL in a page-level state variable. Finally, add a third action using a Custom Action (Dart) that performs an HTTP PUT to the SAS URL with the file bytes. The SAS URL itself is not a secret — it is time-limited and scope-limited by design, so it is safe to use in Dart. After the upload, call a second Function endpoint to register the blob path in your Cosmos DB record so you can retrieve it later.
1// Azure Function: generate SAS URL (Node.js)2const { BlobServiceClient, generateBlobSASQueryParameters, BlobSASPermissions, StorageSharedKeyCredential } = require('@azure/storage-blob');34module.exports = async function (context, req) {5 const accountName = process.env.BLOB_ACCOUNT_NAME;6 const accountKey = process.env.BLOB_ACCOUNT_KEY;7 const containerName = 'uploads';8 const blobName = req.query.filename;910 const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);11 const sasToken = generateBlobSASQueryParameters({12 containerName,13 blobName,14 permissions: BlobSASPermissions.parse('cw'),15 startsOn: new Date(),16 expiresOn: new Date(Date.now() + 10 * 60 * 1000) // 10 min17 }, sharedKeyCredential).toString();1819 const sasUrl = `https://${accountName}.blob.core.windows.net/${containerName}/${blobName}?${sasToken}`;20 context.res = { body: { sasUrl } };21};Pro tip: Set the SAS URL expiry to the minimum time needed for the upload (10 minutes is usually plenty). Never return the Blob account key itself — only the time-limited SAS URL.
Expected result: Tapping the upload button in FlutterFlow calls the Function, receives a SAS URL, and completes the upload to Blob Storage. The file appears in the Azure Portal under your container.
Parse Azure JSON responses into Data Types and bind to widgets
Azure services return verbose JSON, so careful mapping in FlutterFlow is essential. After testing your API Calls and confirming they return data, go to each API Call → Response & Test tab → Generate JSON Paths. FlutterFlow will list all the nested fields it detected. For Cosmos DB responses, results typically come under an array you defined in your Function's response shape; for Azure Functions returning Cosmos data, you might wrap them in a top-level 'items' array — set your JSON path to $.items to extract the list. Next, create a FlutterFlow Data Type (left nav → Data Types → + Add) that mirrors the fields in your response. For example, if Cosmos returns { id, name, quantity, updatedAt }, create a Data Type with those four fields using the correct types (String, String, Integer, String/DateTime). Back in your API Call definition, map the JSON path for each field to the corresponding Data Type field. Now when you drag a ListView onto your canvas and set its data source to this API Call, FlutterFlow knows the schema and auto-suggests text fields, image URLs, and date formatters for each column. For the Cosmos DB item detail page, use a Dynamic Route and pass the item id as a parameter, then make a second API Call (GET /getItem?id={{itemId}}) to fetch the full record. This pattern keeps your API calls lean and your widgets reactive.
Pro tip: If Azure returns PascalCase field names (e.g., ProductName, UnitPrice), make your JSON path expressions match exactly — $.items[*].ProductName — since FlutterFlow JSON path matching is case-sensitive.
Expected result: Your ListView populates with real data from Azure. Each row shows the fields mapped from the Cosmos DB response, and tapping a row navigates to the detail page with the correct item loaded.
Test on device and handle 401/403 token expiry
Run your FlutterFlow app in Test mode first to catch obvious issues, but for full end-to-end validation — especially API Call behavior and any custom Dart actions — use Run mode on a device or emulator. In Test mode, FlutterFlow uses a proxy that can mask certain CORS and auth issues, so a test that passes in the browser may still fail on a real device if your Function's CORS settings are not configured correctly. For auth errors, 401 Unauthorized typically means the 'x-functions-key' header is missing or wrong, or an AAD token has expired. 403 Forbidden usually means the Function key is valid but the token lacks permission on the downstream resource. Build an error state on every page that makes API calls: check the API response code and show a user-friendly message (e.g., 'Session expired — please refresh') rather than a blank screen. Azure Functions on the Consumption plan experience cold starts — the first request after a period of inactivity can take 2–5 seconds. Add a loading indicator (CircularProgressIndicator widget or a shimmer layout) to every screen that awaits an API response. For production apps with latency-sensitive paths, consider moving those Functions to the Premium plan, which keeps instances warm. If you see timeout errors during heavy load, check the Function App's scale-out settings and increase the timeout in host.json.
Pro tip: In the Action Flow Editor, use the 'API Response' condition node after every API Call action to branch on success vs. error — then show an alert dialog for 4xx/5xx responses instead of silently failing.
Expected result: Your app runs successfully on a real device. API calls complete with 200 responses, file uploads land in Blob Storage, and error states display correctly on 401/403 responses.
Common use cases
Project management app with file attachments stored in Blob Storage
A FlutterFlow app where users can upload project documents, images, and PDFs. When a user picks a file, your Azure Function generates a short-lived SAS URL; FlutterFlow performs a direct PUT upload to Blob Storage using that URL. A second Function endpoint returns the list of files for a project.
Build a project management app where users can upload and view project documents stored in Azure Blob Storage, with each file linked to a project record in Cosmos DB.
Copy this prompt to try it in FlutterFlow
Inventory tracking app backed by Cosmos DB
A cross-platform inventory app where warehouse staff scan barcodes and update stock counts. FlutterFlow calls an Azure Function that reads and writes to a Cosmos DB container via its SQL REST API, returning JSON that maps to FlutterFlow Data Types bound to a ListView.
Create an inventory tracking app with barcode scanning that reads and updates product quantities in a Cosmos DB database through an Azure Functions backend.
Copy this prompt to try it in FlutterFlow
Customer portal calling Azure-hosted business logic
A customer-facing mobile app that triggers complex business workflows — pricing calculations, approval chains, or third-party API orchestration — running in Azure Functions. FlutterFlow sends action requests and displays the results without needing to know the underlying logic.
Build a customer portal where users can submit service requests, check order status, and receive real-time pricing — all powered by Azure Functions business logic.
Copy this prompt to try it in FlutterFlow
Troubleshooting
XMLHttpRequest error / CORS policy blocked in FlutterFlow web preview
Cause: The Azure Function App or Blob Storage endpoint does not include the FlutterFlow preview or published domain in its CORS allowed-origins list.
Solution: In the Azure Portal, go to your Function App → API → CORS. Add https://app.flutterflow.io (for the editor preview) and your published FlutterFlow domain (e.g., https://yourapp.flutterflow.app). For Blob Storage, set CORS rules in Storage Account → Resource sharing (CORS) under the Blob service tab. Save and wait 1–2 minutes for the changes to propagate.
401 Unauthorized when calling the Azure Function
Cause: The 'x-functions-key' header is missing, the wrong key is being used, or the key has been regenerated in the Azure Portal.
Solution: In the Azure Portal, navigate to your Function App → Functions → {your function} → Function Keys → default. Copy the current key value. In FlutterFlow, update the header value in your API Call Group (API Calls panel → your group → Headers) or the App Values constant where you store it. Confirm the header name is exactly 'x-functions-key' (lowercase, with hyphens).
Azure Function returns correct data in Postman but FlutterFlow widgets show empty
Cause: The JSON path expressions in FlutterFlow do not match the actual structure of the Azure response, often because of PascalCase field names or an unexpected nesting level.
Solution: Open the API Call → Response & Test tab → paste a real response → click Generate JSON Paths again. Verify each path expression against the actual JSON. If results are nested under 'items', the list path should be $.items and individual field paths should be $.items[0].FieldName. Update the Data Type field mappings to match.
First API call after app idle takes 3–5 seconds with no loading indicator
Cause: Azure Functions on the Consumption plan have cold starts — the first request after an idle period spins up a new instance.
Solution: Add a loading state to your page: in the widget tree, wrap your ListView in a Conditional widget that shows a CircularProgressIndicator while the API call is in-flight (use an isFetching page state boolean). For production apps, consider the Azure Functions Premium plan (Elastic Premium EP1+) which keeps at least one instance warm, eliminating cold starts.
Best practices
- Never store Azure account keys, Cosmos DB resource keys, or AAD client secrets in FlutterFlow variables, App Values, or Dart code — all secrets belong in Azure Function Application Settings.
- Create one API Group per Azure service (Functions, Blob, Cosmos) with its own base URL and auth header, rather than trying to use a single group for all Azure calls.
- Enable CORS on both your Azure Function App and any Blob Storage containers before testing in FlutterFlow's web preview — this is the most common source of silent failures.
- Use short-lived SAS URLs (10–15 minutes) for Blob Storage uploads; never return the storage account key to FlutterFlow.
- Add loading indicators on every screen that calls Azure — cold starts on the Consumption plan can add 2–5 seconds to the first request after idle periods.
- Implement server-side AAD token refresh inside the Function; never rely on FlutterFlow to manage OAuth token expiry.
- Map Cosmos DB and Function JSON responses to FlutterFlow Data Types immediately after testing API Calls — typed data makes widget binding far easier and prevents runtime null-reference errors.
- Set up budget alerts in the Azure Portal even on the free tier — Azure Functions Consumption and Cosmos DB serverless can scale unexpectedly if your app goes viral.
Alternatives
Firebase offers native FlutterFlow integration (one-click setup) and is the recommended choice if you're starting fresh; Azure is better when your company already has Azure infrastructure or enterprise licensing.
Google Cloud Functions integrate more naturally with FlutterFlow's Firebase-native ecosystem via Callable Functions; choose Azure Functions when your organization is Azure-first or when you need AAD-based identity.
AWS S3 with a Lambda proxy is the AWS equivalent of Azure Blob + Functions; choose based on which cloud your existing infrastructure lives on.
Frequently asked questions
Is there a native Azure connector in FlutterFlow?
No. FlutterFlow does not have a built-in Azure connector the way it does for Firebase or Supabase. You configure each Azure service as a separate API Call group — Azure Functions get their own group, Blob Storage gets another, and so on. This manual setup takes a bit more time but gives you full control over which endpoints you expose.
Can I store my Azure account key or client secret in FlutterFlow's App Values?
No — this is not safe. App Values in FlutterFlow are compiled into your Flutter app's binary, which is inspectable. Any secret stored there can be extracted from a downloaded APK or IPA. Store all Azure credentials in your Azure Function's Application Settings and never return them to the client.
Will my FlutterFlow app work on iOS, Android, and web with this Azure setup?
Yes, with one caveat: CORS must be configured on your Azure Function App and Blob Storage for web builds. Native iOS and Android builds do not enforce CORS (the OS makes the HTTP call, not a browser), but the FlutterFlow web preview and your published web app do. Enable CORS in the Azure Portal before testing in the FlutterFlow browser editor.
How do I handle Azure AD authentication for my users?
The recommended pattern is to use FlutterFlow's built-in Firebase Auth (or Supabase Auth) to authenticate your users and get a user token, then pass that token to your Azure Function. The Function validates the token and uses its own AAD service principal credentials to access Azure resources. This keeps AAD completely server-side and gives you a clean user identity model in your app.
Do I need to upgrade from the Azure free tier to use Functions with FlutterFlow?
Not for prototyping. The Azure Functions Consumption plan includes 1 million free executions per month and requires no upfront commitment. Blob Storage has a generous free trial period. You only need to plan for paid usage once your app has real traffic — and even then, Consumption plan costs are typically very low for apps with under 100,000 daily active users. Check Azure's current pricing page for exact numbers.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation