In the world of software, we build complex systems from simple, well-defined primitives. We have functions, classes, and components. Yet, when it comes to a company's core business processes—invoicing a customer, onboarding a new user, enriching a sales lead—we often resort to a tangled web of brittle scripts, monolithic services, and opaque third-party tools.
This complexity is a silent tax on growth. It makes processes hard to understand, difficult to change, and nearly impossible to debug when they inevitably break.
What if we could apply the same rigor and clarity of modern software development to our business operations? This is the core principle of the Business-as-Code Manifesto: Your company's operational logic should be defined, versioned, and executed as clean, composable code.
The foundation of this entire paradigm is the atomic action.
At the heart of the .do platform lies a simple yet powerful concept: the action.do. An action is the smallest, indivisible unit of work in any agentic workflow. It’s a self-contained, reusable function that performs a single, specific task.
Think of it as the atom of your business logic.
Each action is a reusable, observable, and composable building block. By encapsulating a single task—from sending an email to running a complex calculation—you create the foundation for reliable, scalable business automation.
An action isn't an abstract concept; it's a concrete piece of code with a well-defined structure. On the .do platform, defining an action is straightforward. You give it a name, define its inputs, and provide a handler function that contains the core logic.
Here’s how you would define an action to enrich a user's profile using Clearbit and update your database:
import { Do } from '@do-platform/sdk';
// Initialize the .do client with your API key
const-do = new Do(process.env.DO_API_KEY);
// Define a new atomic action to enrich user data
const enrichUserAction = await-do.action.create({
name: 'enrich-user-profile',
description: 'Fetches user data from Clearbit and updates the DB.',
inputs: {
email: 'string',
},
handler: async (inputs) => {
const userData = await clearbit.lookup(inputs.email);
const dbResult = await db.users.update({ email: inputs.email, data: userData });
return { success: true, userId: dbResult.id };
}
});
console.log('Action created:', enrichUserAction.id);
This enrich-user-profile action can now be called from anywhere in your system, by any agent or workflow, simply by referencing its name and providing a valid email. The underlying logic is completely encapsulated, versioned, and monitored by the .do platform.
You might be thinking, "This looks like a serverless function." While there are similarities, an action.do is a higher-level abstraction designed specifically for building business workflows.
Unlike a standard serverless function, a .do Action is a fully managed, versioned, and observable entity within our platform. It comes with:
This focus allows you to concentrate on the what—the business logic—while the .do platform handles the how.
A crucial design principle of the .do platform is that actions are atomic and cannot call other actions.
This might seem limiting at first, but it's a core feature that ensures robustness. An action should do one thing and do it well. For orchestration—the process of sequencing multiple actions—you use a .workflow.do agent.
This separation of concerns is the secret to building systems that are both complex and comprehensible. When a process fails, you know exactly where to look: was it the send-welcome-email action itself, or the orchestration logic in the workflow? This clarity eliminates guesswork and drastically simplifies debugging.
By embracing atomic actions, you are adopting a manifesto for building a better, more resilient company—one where your business is the software.
Q: What is an 'atomic action' on the .do platform?
A: An atomic action is the smallest, indivisible unit of work in a workflow. It's a self-contained, reusable function that performs a single, specific task, like 'send an invoice' or 'update a CRM record'. This atomicity ensures reliability and simplifies debugging.
Q: How is an action.do different from a serverless function?
A: While similar, a .do Action is a fully managed, versioned, and observable entity within our platform. It includes built-in input validation, logging, and security, and is designed to be seamlessly composed into larger Agentic Workflows, abstracting away infrastructure concerns.
Q: Can actions call other actions?
A: No, actions are designed to be atomic. To orchestrate a sequence of actions, you use a .workflow.do agent. This separation of concerns—single tasks in action.do and orchestration in workflow.do—is a core principle for building robust and scalable systems.
Q: What kind of logic can I put inside an action?
A: An action handler can contain virtually any code: API calls to third-party services, data transformations, database queries, or complex business logic. The key is that the action should focus on successfully completing one well-defined task.