
Imagine you're building a Canvas App for your sales team. They want to look up real-time shipping rates from FedEx, pull weather forecasts for field technicians, or query your company's internal inventory system. The data they need lives outside of Microsoft's ecosystem — it lives in a third-party service or a custom backend that exposes a REST API. Out of the box, Power Apps has no idea how to talk to that system. That's where Custom Connectors come in.
A Custom Connector is essentially a bridge you build yourself. You describe the API — its address, its authentication method, and the shape of its requests and responses — and Power Apps uses that description to generate a clean, reusable connection your app can call just like any other data source. Once you've built one, calling an external API from a Canvas App feels as natural as reading a SharePoint list.
By the end of this lesson, you'll have built a working Custom Connector from scratch and wired it into a Canvas App. We'll use a real, free public API (OpenWeatherMap) so you can follow along without needing a corporate backend.
What you'll learn:
Before diving in, you should be comfortable with:
Text property)You'll also need:
Before you touch a single screen in Power Apps, you need a mental model of what you're actually connecting to.
A REST API (Representational State Transfer Application Programming Interface) is a way for software systems to communicate over the internet using the same protocol your browser uses to load web pages: HTTP. When you navigate to a website, your browser sends an HTTP request to a server, and the server sends back HTML. A REST API works the same way, except instead of HTML, the server sends back structured data — almost always in a format called JSON (JavaScript Object Notation).
Here's what a simple API request looks like for the OpenWeatherMap Current Weather endpoint:
GET https://api.openweathermap.org/data/2.5/weather?q=Chicago&appid=YOUR_API_KEY&units=metric
Breaking this down:
GET is the HTTP method — it means "I want to read data." Other methods include POST (create), PUT (update), and DELETE.https://api.openweathermap.org is the base URL — the address of the server./data/2.5/weather is the endpoint path — the specific resource you're requesting.?q=Chicago&appid=YOUR_API_KEY&units=metric are query parameters — key-value pairs that customize the request. The ? starts the list, and & separates each parameter.The server responds with JSON that looks something like this:
{
"name": "Chicago",
"main": {
"temp": 14.3,
"humidity": 72
},
"weather": [
{
"description": "light rain"
}
]
}
This is the raw data your Canvas App will eventually receive. The Custom Connector's job is to translate between this raw HTTP world and the structured, typed world that Power Apps expects.
Think of a Custom Connector as a contract document between Power Apps and an external API. In that document, you specify:
Once you've written that contract, Power Apps can auto-generate a connector that any app in your environment can use. You define it once, and every app benefits.
Important: Custom Connectors live at the environment level in Power Platform, not inside a single app. Any Canvas App, Power Automate flow, or even a Logic App in the same environment can use a connector you create.
Log in to Power Apps at make.powerapps.com. In the left navigation panel, look for "More" (sometimes represented by three dots or an expandable section at the bottom of the nav) and then select "Discover all" or navigate directly to Data → Custom Connectors. Depending on your version of the interface, you may also find it by expanding the left nav and clicking "Custom Connectors" directly.
You'll land on a page that lists any connectors you've already created (probably none yet). Click the "+ New custom connector" button in the top-right corner. A dropdown will appear with several options:
For this lesson, choose "Create from blank" because manually building the connector teaches you exactly what each field means. Give it a name — something like OpenWeatherMap — and click Continue.
You're now inside the Custom Connector editor, which has five tabs across the top: General, Security, Definition, Code (preview), and Test. We'll work through the first four.
The General tab is where you describe the connector at a high level.
Fill in the following fields:
HTTPS. Always use HTTPS for real APIs. HTTP transmits data unencrypted.api.openweathermap.org. This is the domain of the API server — no https:// prefix here, just the domain./data/2.5. This is the path prefix that all of this API's endpoints share. By extracting it here, you don't have to repeat it in every action definition.You can optionally add a description and an icon/color to make the connector identifiable in the connector gallery. For now, leave those as defaults.
Click Security → to move to the next tab.
The Security tab defines how your connector proves its identity to the API. OpenWeatherMap uses API Key authentication — a string of characters that acts like a password, passed along with every request.
Under Authentication type, open the dropdown and select "API Key".
Three new fields will appear:
API Key.appid. (OpenWeatherMap expects the key as a query parameter named appid.)Query. This tells the connector to append &appid=YOUR_KEY to the URL automatically.Tip: Some APIs want the key in a Header instead of a query parameter (e.g.,
Authorization: Bearer YOUR_TOKEN). Always check the API documentation to confirm whether your key goes in the URL or the request header.
Click Definition → to continue.
The Definition tab is the heart of the connector. Here you define every API endpoint (called an action) that your apps will be able to call.
Click "+ New action" on the left side of the screen.
Fill in the action metadata on the right:
Get Current Weather — a human-readable labelReturns current weather conditions for a given city — shown as help text in Power Automate and Power AppsGetCurrentWeather — a unique, code-friendly identifier with no spaces. This becomes the function name in Power Fx.important — this controls whether the action is prominently featured in the UINow scroll down to the Request section. This is where you describe what data the action needs from the caller.
Click "+ Import from sample". A panel will slide in asking you to provide a sample request. This is a fantastic shortcut — instead of manually defining every parameter, you paste in a real example URL and the editor parses it for you.
Fill in the form:
GEThttps://api.openweathermap.org/data/2.5/weather?q=Chicago&units=metricClick Import. Power Apps will parse the URL and automatically create two query parameters: q and units. You'll see them listed under the Request section.
Let's improve these parameters so callers understand what they're for. Click on the q parameter to expand it and set:
City name (e.g., London, Chicago, Tokyo)YesClick on units and set:
Temperature units: metric (Celsius), imperial (Fahrenheit), or standard (Kelvin)metricNo (we provided a sensible default)Now scroll down to the Response section. Click "+ Add default response", then click "+ Import from sample" within the response panel. Paste in a realistic JSON example of the API response:
{
"name": "Chicago",
"main": {
"temp": 14.3,
"humidity": 72,
"feels_like": 12.1
},
"weather": [
{
"main": "Rain",
"description": "light rain"
}
],
"wind": {
"speed": 5.2
}
}
Click Import. Power Apps will parse the JSON and create a strongly-typed response schema — it now knows that the response has a name field (string), a main.temp field (number), and so on. This schema is what allows Power Fx to offer autocomplete when you reference the response in your app.
Click "✓ Create connector" in the top-right corner to save everything so far.
Before wiring this into an app, verify it actually works. Click the Test tab.
You'll be prompted to create a connection first. Click "+ New connection". A dialog will ask for your OpenWeatherMap API key — paste it in and click Create. This stores the key securely as a connection credential.
Back on the Test tab, you should now see your GetCurrentWeather action listed. Expand it and you'll see input fields for q and units. Type a city name like Seattle in the q field and leave units as metric.
Click "Test operation". After a moment, you should see a 200 status code (HTTP's way of saying "success") and the full JSON response body displayed below.
If you see a 401 status code, your API key is wrong or hasn't activated yet (new keys can take up to 10 minutes). Double-check the key in your OpenWeatherMap account dashboard.
If you see a 404 status code, the URL path is wrong. Go back to the Definition tab and verify the action's URL path is
/weather(since the base URL already contains/data/2.5).
Now for the payoff. Open Power Apps and create a new Blank Canvas App (phone layout works fine for this demo).
Add the connector as a data source:
In the left panel, click the Data icon (cylinder shape), then click "+ Add data". In the search box, type OpenWeatherMap. Your custom connector will appear — click it. If prompted to create a connection, select the connection you already created in the test step.
Build the UI:
Add these controls to your canvas:
Default property to "Chicago" and its HintText to "Enter a city name". Rename this control to txtCity by clicking the control name in the Tree View and editing it.Get Weather. Rename it btnGetWeather.lblCity, lblTemp, lblDescription, and lblHumidity.Add a variable to store the response:
Select the button btnGetWeather and set its OnSelect property to:
Set(
weatherResult,
OpenWeatherMap.GetCurrentWeather(
txtCity.Text,
"metric"
)
)
Here's what's happening: OpenWeatherMap.GetCurrentWeather() is the function Power Apps generated from your connector. The first argument maps to the q parameter (city name), and the second maps to units. The result gets stored in a variable called weatherResult.
Wire up the display labels:
Now set the Text property of each label:
// lblCity
weatherResult.name
// lblTemp
"Temperature: " & Text(weatherResult.main.temp) & "°C"
// lblDescription
weatherResult.weather.description
// lblHumidity
"Humidity: " & Text(weatherResult.main.humidity) & "%"
Note on the weather description: OpenWeatherMap returns
weatheras an array (notice the square brackets in the JSON). Power Apps will return this as a table. To get the first item's description, you may need to use:First(weatherResult.weather).description
Save and preview the app by pressing F5 or clicking the Play button. Type a city name, click Get Weather, and watch the labels populate with live data from the OpenWeatherMap API.
Once you have the basic weather app working, extend it with these challenges:
Challenge 1: Add a second Text Input that lets the user choose between metric, imperial, and standard units. Update the button's OnSelect formula to use that input instead of hardcoding "metric". Update the temperature label to show the appropriate unit symbol based on the selection.
Challenge 2: Add error handling. The IfError() function in Power Fx lets you gracefully handle failed API calls. Wrap your Set() call with IfError() and display a friendly message in a label if the city isn't found.
Challenge 3: Add a second action to your Custom Connector — OpenWeatherMap's free tier also offers a 5-day forecast endpoint at /forecast?q={city}&units={units}. Define this action in your connector, import it into the app, and display the forecast in a Gallery control.
"I can't find my custom connector when adding data to my app." Custom Connectors are environment-specific. Make sure your app and your connector are in the same Power Platform environment. Check the environment name in the top-right corner of make.powerapps.com.
"The connector test passes but the app shows blank labels." This usually means the response schema doesn't match what the API is actually returning, or the variable name in your formula doesn't match the connector name. Open the Power Fx formula bar and look for any red underlines indicating unresolved names.
"I'm getting a CORS error or network error in the app preview." Custom Connectors route all traffic through Microsoft's connector infrastructure, so actual CORS errors are rare. If you see a network error, the issue is almost always authentication — your API key wasn't passed correctly. Go back to the connector's Test tab and confirm the key is valid.
"The weather.description field shows a whole table, not a single string."
This is the array issue mentioned earlier. When JSON returns an array, Power Apps sees it as a table. Use First(weatherResult.weather).description to extract the first element.
"My Base URL and action path are doubling up."
If your base URL is /data/2.5 and you accidentally set the action path to /data/2.5/weather, the full URL becomes /data/2.5/data/2.5/weather. The action path should only contain what comes after the base URL — in this case, just /weather.
You've just built something genuinely powerful. Let's recap what you accomplished:
The pattern you've learned here — describe the API, create the connector, use it in an app — applies to virtually any REST API in the world. Whether you need to connect to Salesforce, Stripe, an internal data service, or a public government dataset, the process is the same.
Where to go from here:
The ability to connect to any API in the world transforms Canvas Apps from a tool for accessing Microsoft data into a platform for integrating your entire technology landscape. That's a genuinely important skill, and you now have the foundation to build on it.
Learning Path: Canvas Apps 101