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=localhost: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