Building automated workflows sounds simple at first. A new user signs up? Just create a database record, send a welcome email, and update the CRM. Easy, right? You wrap the logic in a function, maybe add a try-catch block, and deploy. But what happens when this "simple" workflow runs at scale in a distributed environment?
What if your email service API has a brief outage? Or your CRM update times out? Your try-catch block might log the error, but the system is now in an inconsistent state: the user exists and has an email record, but your sales team has no idea they exist. If you just re-run the entire process, you risk creating a duplicate user or sending a second, confusing welcome email.
This is the fundamental challenge of distributed systems: partial failures. Traditional error handling isn't enough. To build truly robust and scalable automated workflows, you need to move beyond try-catch and embrace a more powerful concept: atomic actions.
The core problem is that try-catch is stateless. It handles an error in the moment but has no memory of what succeeded before the failure. In a multi-step workflow, this is a critical flaw.
Let's break down our user signup flow:
The system is now inconsistent. A naive retry of the entire workflow leads to side effects:
To handle this properly, your code would need to become significantly more complex. You'd have to build your own state machine, check if the user already exists, see if an email has already been sent, and only then attempt the CRM update.
This is the challenge of idempotency—ensuring that performing an operation multiple times has the same effect as performing it once. Building this logic from scratch for every step of every workflow is a tedious, error-prone task that distracts from writing the core business logic.
What if you could define each step of your workflow as an independent, indivisible unit of work? A unit that is guaranteed to either succeed completely or fail cleanly, with no side effects?
This is the principle behind atomic actions on the action.do platform.
Think of it like a database transaction. An atomic action encapsulates a single task, like "send a welcome email," into a reusable, API-driven component. The platform treats this action as the smallest unit of work in any agentic workflow. It abstracts away all the messy infrastructure code for retries, state management, and logging, allowing you to focus purely on what the action needs to do.
This approach provides the building blocks for reliable business process automation.
With .do, you define these building blocks as simple, clean code. You write the handler logic, and the platform makes it fault-tolerant.
import { Action, client } from '@do-sdk/core';
// Define an atomic action as code
const sendWelcomeEmail = new Action({
name: 'send-welcome-email',
handler: async (inputs: { userId: string }) => {
const user = await db.users.find(inputs.userId);
if (!user) {
throw new Error('User not found.');
}
await email.send({
to: user.email,
subject: 'Welcome to .do!',
body: `Hi ${user.name}, welcome aboard!`
});
return { success: true, messageId: '...' };
}
});
// Execute the action via the SDK
const result = await client.action('send-welcome-email').invoke({
userId: 'usr_12345'
});
Here’s what’s happening:
Under the hood, the .do platform wraps your action with enterprise-grade reliability:
Because each Action is a reliable, atomic building block, composing them into complex workflows is simple and safe. You can easily sequence, parallelize, and orchestrate multiple Actions to model any business process.
If our three-step signup workflow fails at the "Update CRM" action, the platform knows that the first two actions succeeded. It can then intelligently retry only the failed action until it succeeds, without causing unwanted side effects. Your workflow picks up exactly where it left off, ensuring the entire process eventually completes with consistency and accuracy.
Stop fighting with distributed state and endless try-catch blocks. Start defining your business logic as atomic actions as code and let the platform handle the complexity of guaranteed execution.
Q: What is an 'atomic action' on the .do platform?
A: An atomic action is the smallest, indivisible unit of work in a workflow, like 'send an email' or 'update a CRM record'. It's designed to either succeed completely or fail without side effects, ensuring process integrity and reliability.
Q: How are .do Actions different from standard API endpoints?
A: While triggered via API, Actions on .do are stateful, auditable, and designed for agentic workflows. They include built-in error handling, retries, and logging, abstracting away boilerplate infrastructure code so you can focus purely on business logic.
Q: Can I chain multiple Actions together?
A: Yes. Actions are the fundamental building blocks of .do Workflows. You can easily sequence, parallelize, and orchestrate multiple Actions to model complex business processes as fault-tolerant, scalable Services-as-Software.
Q: What happens if an Action fails during execution?
A: The .do platform provides configurable retry logic and error handling. Because actions are atomic, a failure prevents partial execution, ensuring your system remains in a consistent state. You can also define custom failure handlers and alerts.