Skip to main content

Connecting to External APIs

📚
Prerequisites

This guide assumes you've completed the Node.js Quickstart. You should understand how to define tools with @DaemoTool and register services.

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

Tip

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.

Info

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:

  1. Define the Tool: Describe what the API endpoint does.
  2. Call the API: Use axios or fetch to make the request.
  3. Handle Errors: Catch HTTP errors and return friendly messages.
src/services/weatherService.ts
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:

src/services/daemoService.ts
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:

.env
# Daemo
DAEMO_AGENT_API_KEY=your_agent_api_key_from_app_daemo_ai
DAEMO_GATEWAY_URL=https://engine.daemo.ai:50052

# External APIs
WEATHER_API_KEY=your_weather_api_key

Best Practices​

  1. Use Zod Schemas: Always define inputSchema so the AI knows what parameters to pass.
  2. Handle Errors Gracefully: Catch HTTP errors and throw descriptive messages the AI can relay to users.
  3. Limit Response Data: Only return fields the AI needs — don't dump raw API responses.
  4. Add Timeouts: Use axios timeouts to prevent hanging requests.
  5. Rate Limiting: If the API has rate limits, consider caching or throttling.

Next Steps​