Connecting to External APIs
Learn how to connect your agent to third-party REST or GraphQL APIs.
Overview
Connecting to an external API (like Stripe, Salesforce, or a Weather API) is one of the most common use cases for Daemo agents. You simply wrap the API call inside a @DaemoTool.
Project Structure
Here's where each file goes in a typical Daemo + External API project:
your-project/
├── src/
│ ├── app.ts # Express server + Daemo init
│ ├── services/
│ │ ├── daemoService.ts # DaemoBuilder registration
│ │ ├── weatherService.ts # Weather API functions
│ │ └── stripeService.ts # Stripe API functions (example)
│ └── utils/
│ └── apiClient.ts # Shared HTTP client (optional)
├── .env # API keys (never commit!)
├── package.json
└── tsconfig.json
Each code block below shows its file path in the header. Copy each file to the correct location.
The SF 311 Example
We have a complete, production-ready example of connecting to an external API (the Socrata Open Data API) in our SF 311 Agent Template.
Go to the Example Project to see a deep dive into fetching data, handling timeouts, and mapping API responses.
Basic Pattern
The general pattern for any API integration is:
- Define the Tool: Describe what the API endpoint does.
- Call the API: Use
axiosorfetchto make the request. - Handle Errors: Catch HTTP errors and return friendly messages.
import { DaemoTool } from '@daemo/sdk';
import axios from 'axios';
import { z } from 'zod';
export class WeatherService {
private apiKey = process.env.WEATHER_API_KEY;
@DaemoTool({
description: "Get the current weather for a city.",
inputSchema: z.object({
city: z.string().describe("City name (e.g. London)")
})
})
async getWeather(input: { city: string }) {
try {
const response = await axios.get(
`https://api.weatherapi.com/v1/current.json`,
{
params: { key: this.apiKey, q: input.city }
}
);
return {
temp_c: response.data.current.temp_c,
condition: response.data.current.condition.text
};
} catch (err) {
// Return a message the AI can understand
throw new Error(`Could not fetch weather: ${err.message}`);
}
}
}
Authentication
Always handle API keys securely:
- Store keys in
.env - Never hardcode keys in your function
- If the API requires OAuth (user-level auth), you will need to pass tokens into your function logic (a more advanced topic).
Handling Large Responses
APIs often return huge JSON objects. Do not return the entire object to the LLM. It wastes tokens and confuses the model.
❌ Bad:
return response.data; // Returns 50 fields, most irrelevant
✅ Good:
// Pick only what the AI needs to answer user questions
return {
id: response.data.id,
status: response.data.status,
total: response.data.amount_total
};
Registering Your Service
Don't forget to register your service with Daemo:
import { DaemoBuilder, SessionData } from "@daemo/sdk";
import { WeatherService } from "./weatherService";
const systemPrompt = `You are a helpful assistant with access to weather data.
When asked about the weather, use the getWeather function.
Always provide temperatures in both Celsius and Fahrenheit.`;
export function initializeDaemoService(): SessionData {
const builder = new DaemoBuilder()
.withServiceName("weather_service")
.withSystemPrompt(systemPrompt);
const weatherService = new WeatherService();
builder.registerService(weatherService);
return builder.build();
}
Environment Variables
Create a .env file for your API keys:
# Daemo
DAEMO_AGENT_API_KEY=your_agent_api_key_from_app_daemo_ai
DAEMO_GATEWAY_URL=localhost:50052
# External APIs
WEATHER_API_KEY=your_weather_api_key
Best Practices
- Use Zod Schemas: Always define
inputSchemaso the AI knows what parameters to pass. - Handle Errors Gracefully: Catch HTTP errors and throw descriptive messages the AI can relay to users.
- Limit Response Data: Only return fields the AI needs — don't dump raw API responses.
- Add Timeouts: Use
axiostimeouts to prevent hanging requests. - Rate Limiting: If the API has rate limits, consider caching or throttling.
Next Steps
- Test Your Agent — CLI scripts, Playground, and debugging guides
- SF 311 Example — Production-ready API integration
- Supabase Integration — Add database storage alongside your API calls