As developers, we've all been there. The request sounds simple: "Can you create a service to score our new sales leads?" You nod, thinking about the core logic—a few if statements, maybe a simple scoring algorithm. It's a 30-line function, tops.
But then reality sets in. That 30-line function needs an entire ecosystem to become a reliable, production-ready service. You need to:
Suddenly, your simple function is a multi-day project filled with boilerplate and operational overhead. The valuable business logic is buried under layers of undifferentiated heavy lifting.
What if you could skip all that? What if you could execute functions as reliable services, focusing only on the code that delivers value?
With Functions.do, you can. Our agentic workflow platform is built for exactly this—transforming business logic into typesafe, production-ready APIs without the complexity. Let's walk through how to take a lead-scoring idea from a concept to a live API in under 10 minutes.
Our business goal is to automatically qualify leads based on a few key data points: company size, industry, and whether they have a confirmed budget. The logic is straightforward: assign a score and provide a reason. This is a classic example of "Business-as-Code."
Traditionally, you'd start by writing the core function in TypeScript. Then, you'd wrap it in an Express server, add a validation library like Zod or Joi, set up a deployment script, and so on. The final code would be 90% boilerplate and 10% business logic.
Functions.do flips the script. You define the what and the how, and our platform handles the where and the when. Here’s how you build our lead scoring service on the platform.
First, define the shape of your input data using a TypeScript interface. This isn't just for developer convenience; it's a binding contract that Functions.do uses to enforce type safety at the edge.
// Define the input type for your function
interface Lead {
companySize: number;
industry: string;
hasBudget: boolean;
contactEmail: string;
}
// Define the expected output
interface LeadScore {
score: number;
reason: string;
isQualified: boolean;
}
By defining Lead and LeadScore, you've created a source of truth for your service. Our platform will automatically reject any API call that doesn't match the Lead interface.
Now, write your pure business logic. This is a standard TypeScript function. Notice there's no server code, no req/res objects—just a clear, testable unit of work.
To deploy this logic, you'd use the Functions.do SDK to define it as a service.
import { Function } from 'functions.do';
// Assume the interfaces from Step 1 are here
// Define the function agent, linking its logic and types
const scoreLead = Function.define<Lead, LeadScore>({
id: 'score-lead-v1',
handler: async (input): Promise<LeadScore> => {
let score = 0;
let reason = 'Initial score.';
if (input.companySize > 50) {
score += 30;
reason += ' Strong company size.';
}
if (['SaaS', 'FinTech', 'HealthTech'].includes(input.industry)) {
score += 40;
reason += ' Priority industry.';
}
if (input.hasBudget) {
score += 30;
reason += ' Budget confirmed.';
}
return {
score,
reason: reason.trim(),
isQualified: score >= 70,
};
},
});
With your logic defined, deploying is a single command. Save the code above as score-lead.ts and run the CLI (or connect your Git repository for automatic deployments).
fdo deploy score-lead.ts
That's it. Functions.do takes your code and automatically:
You've just created a production-grade software service without writing a single line of infrastructure code.
Now, from any other application, service, or script, you can execute your function using the same SDK. Your function is now a first-class "agent" you can invoke.
import { Function } from 'functions.do';
// Define the input type again for the client-side
// (or share it from a common package)
interface Lead {
companySize: number;
industry: string;
hasBudget: boolean;
}
// Get a client for your function agent
const scoreLead = Function<Lead>('score-lead-v1');
// Execute the function with typesafe inputs
const { score, reason, isQualified } = await scoreLead({
companySize: 250,
industry: 'SaaS',
hasBudget: true,
});
// A top-tier lead!
// -> Lead Score: 100/100 - Strong company size. Priority industry. Budget confirmed.
console.log(`Lead Score: ${score}/100 - ${reason}`);
if (isQualified) {
console.log('This lead is highly qualified!');
// Trigger next step, e.g., another function to add to CRM
}
Notice the power of this approach. The call to scoreLead is fully typesafe. If you tried to pass companySize: '250' as a string, TypeScript would catch the error before you even run the code.
This is just the beginning. The real power of Functions.do is revealed when you orchestrate multiple functions into a cohesive agentic workflow.
Your scoreLead function is one agent. You could easily create another: addToCRM, sendWelcomeEmail, or notifySalesTeam. With Functions.do, you can chain these agents together. The platform manages the state, guarantees execution order, and handles retries and errors between steps, allowing you to model complex business processes as simple, composable functions.
Compared to traditional FaaS platforms like AWS Lambda, Functions.do operates at a higher level of abstraction. We are not just giving you a place to run code; we are providing a managed, typesafe framework to turn business services into robust software.
Ready to stop wrestling with infrastructure and start shipping features?
Visit Functions.do to turn your business logic into powerful, typesafe APIs in minutes.