External API Integration
Master connecting your Buzzy app to external services. Learn Buzzy Functions, API integration, secure key storage, and error handling with step-by-step examples.
Overview
What we're building: A weather dashboard app that fetches real-time data from an external weather API using Buzzy Functions.
Non-technical explanation: Think of APIs like electrical outlets—they provide power (data) that your app can use. Your Buzzy app is like a device that plugs into these outlets to get what it needs. Buzzy Functions act as safe adapters that handle the connection securely.
Time commitment: 4-6 hours total
Setup and API access: 30 minutes
Building Buzzy Function: 1-2 hours
App interface: 1-2 hours
Testing and refinement: 1-2 hours
Difficulty: 🟡 Moderate - Requires understanding of APIs and server-side code
Prerequisites:
✅ Completed Hello World App
✅ Understanding of Data Design
✅ Basic API concepts (HTTP requests, JSON responses)
✅ Reviewed Buzzy Functions documentation
✅ Free API key from weather service (we'll get this together)
What you'll learn:
🔧 Creating Buzzy Functions (AWS Lambda) for API integrations
🔒 Using Buzzy Constants for secure API key storage (AES encryption)
📞 Calling Buzzy Functions from your app actions
📊 Handling API responses and displaying data in Buzzy apps
⚠️ Error handling for network failures and API limits
💾 Caching strategies to improve performance and reduce API calls
Understanding APIs
What Is an API?
API (Application Programming Interface): A way for your app to communicate with external services.
Example uses:
Get weather data (OpenWeatherMap)
Process payments (Stripe)
Send emails (SendGrid)
Get map data (Google Maps)
AI features (OpenAI)
API Communication
Your app → API Request → External Service External Service → API Response → Your app
Request includes:
Endpoint URL
HTTP method (GET, POST, PUT, DELETE)
Headers (authentication, content type)
Body data (for POST/PUT)
Response includes:
Status code (200 = success, 404 = not found, 500 = error)
Response data (usually JSON)
Headers (metadata)
The Weather Dashboard Project
Features:
Search for city weather
Display current temperature, conditions, humidity
Show 5-day forecast
Save favorite cities
Auto-refresh data
APIs we'll use:
OpenWeatherMap API (free tier)
Alternative free weather APIs:
WeatherAPI.com
Tomorrow.io
Open-Meteo (no API key needed)
Step 1: Setup (30 minutes)
Get API Access
OpenWeatherMap:
Go to openweathermap.org
Sign up for free account
Go to API keys section
Copy your API key
Test it works in your browser:
https://api.openweathermap.org/data/2.5/weather?q=London&appid=YOUR_API_KEY&units=metric
API limits (free tier):
60 calls per minute
1,000,000 calls per month
Current weather + 5-day forecast
Buzzy Integration Strategy
The right way: Use Buzzy Functions for external API calls:
Architecture:
Buzzy Constants: Store API key securely with AES encryption
Buzzy Function: AWS Lambda function (Node.js 22) that calls weather API
Buzzy App: Buttons/actions call your Function, which returns weather data
Why Buzzy Functions:
API keys stay secure (never exposed to client)
Server-side execution (no CORS issues)
Can add caching and rate limiting
Professional architecture
Scales automatically on AWS Lambda
Buzzy manages the infrastructure
Buzzy Functions are AWS Lambda functions that run server-side. Your Buzzy app calls them via actions, and they can access external APIs, databases, and other services securely. Learn more about Buzzy Functions.
Plan the Buzzy Application
Data Model in Buzzy:
Cities Datatable:
city_name (text, required)
country_code (text, e.g., "GB", "US")
latitude (number, optional)
longitude (number, optional)
favorited (yes/no, default no)
last_updated (date/time, automatic)
WeatherData Datatable (Subtable of Cities, optional for caching):
temperature (number)
conditions (text, e.g., "Sunny")
humidity (number)
wind_speed (number)
fetched_at (date/time)
Weather Data (not stored, fetched on demand):
temperature
conditions
humidity
wind speed
forecast
Why not store weather data?:
Changes frequently
Would be outdated quickly
Better to fetch fresh each time
User Flow
User opens app
↓
Sees search bar
↓
Enters city name → Searches
↓
App calls weather API
↓
Displays current weather + forecast
↓
User can save as favorite
↓
Favorite cities show on home screen
Step 2: Initial Build with Buzzy AI v3 (45 minutes)
The Prompt
In Buzzy Workspace, create a new app with this prompt:
Create a weather dashboard application:
Data Model:
- Cities Datatable:
- name (text field, required)
- country (text field)
- latitude (number field)
- longitude (number field)
- favorited (yes/no field, defaults to no)
- last_checked (date/time field)
- cached_weather (JSON field, optional, for caching API responses)
- Viewers field set to current user
Screens:
1. Home screen:
- Search input field for city names
- Search button
- List of favorited cities below search (if any)
- Empty state message: "Search for a city to get started" when no favorites
- Each favorited city card shows: name, country, last checked time
- Click on city card to view weather
2. Weather Detail screen:
- City name and country (heading)
- Current temperature (large, prominent)
- Weather condition description
- Additional details: humidity, wind speed
- "Add to Favorites" / "Remove from Favorites" button (depending on favorited status)
- "Refresh Weather" button
- Back button to home
Features:
- Search functionality (we'll add Buzzy Function call in next step)
- Save favorite cities to Cities Datatable
- Mobile-responsive design
- Clean, modern interface
Security:
- Use Viewers field so users only see their own favorited cities
Note: We'll add the actual API integration using Buzzy Functions in the next step.
Step 3: Create Buzzy Function for API Integration (60-90 minutes)
Step 3a: Store API Key in Buzzy Constants
Security first: Never hard-code API keys in your app or Buzzy Functions
Create a Buzzy Constant:
In Buzzy Workspace, go to Settings tab
Click Constants section
Click Add Constant
Name:
WEATHER_API_KEY
Value: [paste your OpenWeatherMap API key]
Description: "OpenWeatherMap API key for weather data"
Save
Buzzy Constants are encrypted and stored securely. Your Buzzy Functions can access them using the BUZZYCONSTANTS()
syntax, but they're never exposed to the client. Learn more about Constants.
Step 3b: Create Buzzy Function for Weather API
Create a new Buzzy Function:
In Buzzy Workspace, go to Settings tab
Click Functions section
Click Add Function
Name:
getWeatherData
Description: "Fetches current weather data from OpenWeatherMap API"
Runtime: Node.js 22
Lambda function code (minimal example):
export const handler = async (event) => {
try {
const cityName = event.cityName;
if (!cityName) {
return {
statusCode: 400,
body: JSON.stringify({ error: 'City name is required' })
};
}
const apiKey = BUZZYCONSTANTS('WEATHER_API_KEY');
const url = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&appid=${apiKey}&units=metric`;
const response = await fetch(url);
if (!response.ok) {
if (response.status === 404) {
return {
statusCode: 404,
body: JSON.stringify({ error: 'City not found' })
};
}
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
return {
statusCode: 200,
body: JSON.stringify({
city: data.name,
country: data.sys.country,
temperature: Math.round(data.main.temp),
conditions: data.weather[0].main,
description: data.weather[0].description,
humidity: data.main.humidity,
windSpeed: data.wind.speed,
lat: data.coord.lat,
lon: data.coord.lon
})
};
} catch (error) {
console.error('Error fetching weather:', error);
return {
statusCode: 500,
body: JSON.stringify({ error: 'Failed to fetch weather data' })
};
}
};
Key points:
Uses
BUZZYCONSTANTS('WEATHER_API_KEY')
to access secure API keyReturns structured response with statusCode and body
Handles errors appropriately
Node.js 22 runtime (uses fetch natively)
Step 3c: Call Buzzy Function from Your App
In Buzzy Workspace, update your app:
Option 1 - Use Buzzy AI to integrate:
Update the search functionality to call the getWeatherData Buzzy Function:
1. When user clicks Search button:
- Show loading indicator
- Call the getWeatherData Function with the city name from search input
- Wait for response
2. On successful response:
- Hide loading indicator
- Navigate to Weather Detail screen
- Pass weather data to the detail screen
- Optionally save city to Cities Datatable if user wants to favorite it
3. On error response:
- Hide loading indicator
- Show error message based on error type:
* 404: "City '[name]' not found. Please check the spelling."
* 500: "Unable to fetch weather data. Please try again later."
* Other: "An error occurred. Please try again."
4. Add loading state:
- Disable search button while loading
- Show spinner or "Loading..." text
Option 2 - Manual configuration in Design tab:
Go to Design tab → Home screen
Click on Search button
In button properties, add Action: Call Function
Select Function:
getWeatherData
Set Parameters:
{ "cityName": "[value from search input]" }
Configure success action: Navigate to Weather Detail screen
Configure error action: Show error message
Add loading indicator component
Step 3d: Display Weather Data
Update Weather Detail screen:
Go to Design tab → Weather Detail screen
Add text components for each piece of weather data
Bind components to the data passed from the Function response:
Temperature →
weatherData.temperature
Conditions →
weatherData.conditions
Description →
weatherData.description
Humidity →
weatherData.humidity
Wind Speed →
weatherData.windSpeed
Add "Add to Favorites" button that saves to Cities Datatable
Test the integration:
Go to Preview mode
Search for a city (e.g., "London")
Verify weather data displays correctly
Test error cases (invalid city name)
Check loading indicators work
Step 4: Add Caching in Buzzy (45 minutes)
Why Cache?
Problems without caching:
API calls cost money (or count against limits)
Slow user experience for repeat views
Wastes bandwidth
Risk of hitting rate limits
Caching strategy in Buzzy:
Store weather data in Cities Datatable (JSON field)
Refresh only if data is old (e.g., > 30 minutes)
Much faster for favorited cities
Reduces Buzzy Function calls by 90%+
Implement Caching in Your Buzzy App
The Cities Datatable already has:
cached_weather
(JSON field) - stores the weather datalast_checked
(date/time field) - tracks when data was fetched
Caching logic approach:
Option 1 - Add cache check to Buzzy Function:
Update your getWeatherData
Function to accept a lastChecked
parameter and return cached data if fresh:
export const handler = async (event) => {
try {
const { cityName, cachedWeather, lastChecked } = event;
// Check if cache is fresh (< 30 minutes old)
if (cachedWeather && lastChecked) {
const cacheAge = (Date.now() - new Date(lastChecked).getTime()) / 1000 / 60;
if (cacheAge < 30) {
return {
statusCode: 200,
body: JSON.stringify({
...cachedWeather,
fromCache: true
})
};
}
}
// Fetch fresh data (same as before)
const apiKey = BUZZYCONSTANTS('WEATHER_API_KEY');
const url = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&appid=${apiKey}&units=metric`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
return {
statusCode: 200,
body: JSON.stringify({
city: data.name,
country: data.sys.country,
temperature: Math.round(data.main.temp),
conditions: data.weather[0].main,
description: data.weather[0].description,
humidity: data.main.humidity,
windSpeed: data.wind.speed,
lat: data.coord.lat,
lon: data.coord.lon,
fromCache: false
})
};
} catch (error) {
return {
statusCode: 500,
body: JSON.stringify({ error: 'Failed to fetch weather data' })
};
}
};
Option 2 - Handle caching in Buzzy app logic:
Use Buzzy AI to implement caching in your app:
Add caching logic to the weather feature:
1. When viewing a favorited city's weather:
- Check if cached_weather field has data
- Check if last_checked is less than 30 minutes ago
- If yes: Display cached weather data without calling Function
- If no: Call getWeatherData Function and update cached_weather and last_checked fields
2. Add "Refresh" button on Weather Detail screen:
- When clicked, force call to getWeatherData Function
- Update cached_weather and last_checked fields
- Show "Refreshed just now" message
3. Display cache status:
- Show "Updated X minutes ago" on weather screen
- Show small indicator when using cached data
4. When favoriting a city:
- Save weather data to cached_weather field
- Set last_checked to current time
5. When unfavoriting a city:
- Optionally clear cached_weather field
Benefits of Caching
User experience:
Instant weather display for favorited cities
Less waiting for API responses
Works better on slow connections
Cost savings:
Fewer Buzzy Function invocations
Fewer external API calls
Better rate limit management
Implementation tips:
Keep cache duration reasonable (15-30 minutes for weather)
Always provide manual refresh option
Show user when data is cached vs fresh
Clear cache if data becomes stale
Step 5: Error Handling in Buzzy (30 minutes)
Comprehensive Error Handling
Error types to handle:
Network errors:
Buzzy Function timeout
External API server down
Connectivity issues
API errors:
Invalid API key (401)
City not found (404)
Rate limit exceeded (429)
Server error (500)
User input errors:
Empty search
Invalid city name
Special characters
Implementation in Buzzy
Update your Buzzy app using the Design tab or Buzzy AI:
Improve error handling throughout the app:
1. Search validation on Home screen:
- Add validation rule: search field must not be empty
- Show error message: "Please enter a city name"
- Disable search button if input is empty
- Trim whitespace from input
- Require minimum 2 characters
2. Function call error handling:
- Configure error action on Search button
- Based on statusCode from Function response:
* 404: Show message "City '[name]' not found. Please check the spelling."
* 500: Show message "Unable to fetch weather data. Please try again later."
* Timeout: Show message "Request timed out. Please try again."
- Add "Try Again" button that re-triggers the search
3. Loading states:
- Show loading spinner while Function is executing
- Disable search button during loading
- Show "Fetching weather data..." message
- Hide loading after response (success or error)
4. User feedback:
- Use clear, friendly error messages
- Avoid technical jargon (don't show "statusCode 500")
- Suggest actions to fix (e.g., "Check spelling" or "Try again")
- Show errors in popup or banner, not blank screens
5. Graceful degradation:
- If Function fails, show cached data if available
- Display "Showing cached data - unable to refresh" message
- Allow user to retry or view other favorited cities
Step 6: Testing in Buzzy Preview Mode (60 minutes)
Test Your Buzzy Function Integration
Test happy path in Preview mode:
Test error cases:
Test Buzzy Function directly (in Settings → Functions):
Test caching (if implemented):
Test edge cases:
Performance Testing in Preview
Testing Buzzy Functions: You can test Functions independently in Settings → Functions before integrating them into your app. This helps debug issues faster by isolating the Function logic from the app UI.
Common Buzzy Function Integration Issues
Issue: Function Timeout
Symptom: Function call times out in Buzzy app
Cause: External API is slow or Function is taking too long
Solution:
Optimize your Function code
Increase Function timeout in Settings (max 30 seconds)
Add timeout handling to external API calls
Consider breaking complex operations into multiple Functions
Issue: Constant Not Found
Symptom: Function returns error about missing BUZZYCONSTANTS
Cause: Constant name misspelled or not created
Solution:
Verify Constant exists in Settings → Constants
Check exact spelling in Function code:
BUZZYCONSTANTS('WEATHER_API_KEY')
Constants are case-sensitive
Redeploy Function after creating/updating Constants
Issue: Function Returns 500 Error
Symptom: Function call always returns statusCode 500
Cause: Error in Function code or external API
Solution:
Test Function directly in Settings → Functions with test input
Check Function logs for error messages
Verify external API key is valid
Add try-catch blocks to handle errors gracefully
Return proper statusCode and error message
Issue: Data Not Passing to Function
Symptom: Function receives empty or undefined parameters
Cause: Incorrect parameter configuration in Buzzy app action
Solution:
In Design tab, check Function call action parameters
Verify parameter names match what Function expects
Use correct syntax to reference form/input values
Test with hardcoded values first to verify Function works
Issue: Slow Performance
Symptom: App feels laggy when calling Functions
Cause: Waiting for Function + external API responses
Solution:
Add loading indicators immediately when Function is called
Implement caching in Datatables (JSON fields)
Show cached data instantly, refresh in background
Optimize Function code to return quickly
Consider async patterns where appropriate
Extending the Buzzy Weather App
Additional features to add:
5-Day Forecast (Create new Buzzy Function):
Create
getWeatherForecast
FunctionUse OpenWeatherMap forecast endpoint
Display forecast cards on weather detail screen
Store forecast in cached_weather JSON field
Weather Alerts (Enhance Buzzy Function):
Fetch severe weather alerts in Function
Show alerts on weather detail screen with warning icon
Add alerts field to Cities Datatable
Highlight cities with alerts on home screen
Multiple Units (App-level preference):
Add "units" field to user profile or app settings
Pass units preference to Buzzy Function
Function converts data based on preference
Toggle between Celsius/Fahrenheit in app
Location Detection (Use browser geolocation):
Add "Use My Location" button on home screen
Capture latitude/longitude from browser
Create Buzzy Function that accepts coordinates
Fetch weather by coordinates instead of city name
Weather History (Store in Subtable):
Create WeatherHistory Subtable under Cities
Each Function call saves a history record
Display temperature trends over time
Show graph using Buzzy's chart components or Code Widget
Share Weather (Export feature):
Format weather data as shareable text
Use browser share API or copy to clipboard
Generate weather card image (via Buzzy Function or external service)
Share to social media
Best Practices Summary
Buzzy Functions for API Integration:
✅ Always use Buzzy Functions for external API calls (never call from client)
✅ Store API keys in Buzzy Constants (AES encrypted)
✅ Handle errors gracefully with proper statusCodes
✅ Implement caching to reduce Function calls and API costs
✅ Show loading states while Functions execute
✅ Provide user-friendly error messages (not technical errors)
✅ Test Functions independently before integrating into app
✅ Use consistent response format (statusCode + body)
What to avoid:
❌ Never expose API keys in app or Function code
❌ Don't call external APIs directly from Buzzy app (use Functions)
❌ Don't skip error handling in Functions
❌ Don't call Functions without showing loading indicators
❌ Don't assume Functions always succeed
❌ Don't show raw error messages to users
Buzzy Functions Architecture Benefits:
Secure API key storage with Constants
Server-side execution (no CORS issues)
Automatic scaling on AWS Lambda
Managed infrastructure by Buzzy
Easy to test and debug independently
Reusable across multiple apps
Next Steps
Now that you understand Buzzy Functions for API integration:
Try integrating different APIs:
AI-Powered Features - Use Buzzy Functions with OpenAI/Anthropic
Payment APIs - Stripe integration via Buzzy Functions
Email APIs - SendGrid for notifications
SMS APIs - Twilio for text messages
Map APIs - Google Maps or Mapbox
Learn more about:
Buzzy Functions & Constants - Full documentation
Security Best Practices - Secure your apps
App Quality & Performance - Optimize your apps
Pattern to remember:
Store secrets in Buzzy Constants
Create Buzzy Function to call external API
Configure app action to call Function
Handle loading states and errors
Display results in your app
Congratulations! You now know how to connect your Buzzy apps to external services using Buzzy Functions. This pattern works for almost any API—payments, AI, maps, emails, and more. You've learned the professional, secure way to integrate third-party services without exposing credentials or dealing with CORS issues.
Last updated