In the world of workflow automation and agentic systems, complexity is the enemy of reliability. A single process, like onboarding a new customer, can involve dozens of interconnected steps: creating a user account, sending a welcome email, updating a CRM, and assigning a task to a support agent. Managing this as a monolithic block of code is a recipe for brittle, hard-to-maintain systems.
The solution starts with granularity. We've previously discussed how action.do allows you to define and execute atomic actions—flawless, single-responsibility tasks that form the bedrock of reliable automation. But what happens when you need to assemble these building blocks into a sophisticated, end-to-end process and offer it to the world?
That's where service.do comes in. It's the next logical step in the Business-as-Code revolution, allowing you to package an entire workflow of atomic actions into a single, robust, and scalable API endpoint.
Before building a skyscraper, you need to perfect the brick. In the .do ecosystem, that brick is the atomic action.
As a refresher, an atomic action is a self-contained, indivisible unit of work. It adheres to the single-responsibility principle and is transactional by nature: it either completes successfully or fails entirely, leaving no messy partial states.
Think of fundamental business operations:
By using action.do to execute these tasks, you gain unparalleled reliability and clarity. Each action is a predictable, testable component.
import { Dō } from '@do-sdk/core';
const dō = new Dō({ apiKey: 'YOUR_API_KEY' });
// Executing a single, atomic action
const result = await dō.action.execute({
name: 'send-welcome-email',
input: {
userId: 'user-12345',
template: 'new-user-welcome',
},
});
// { success: true, transactionId: 'txn_abc_123' }
But a pile of bricks isn't a building. You need an architect's plan to assemble them into something greater.
While action.do is for executing a single task, service.do is for exposing an entire orchestrated sequence of tasks. It transforms your complex workflow into a clean, simple API endpoint that abstracts away the internal complexity.
Imagine our "New Customer Onboarding" process. Internally, it might look like this:
With service.do, you package this entire chain of agentic workflow logic into a single callable service named onboard-new-customer. Now, any application—your frontend, a mobile app, or a partner integration—can trigger this entire multi-step process with one simple, secure API call.
// Hypothetical service.do execution
const newCustomer = await dō.service.execute({
name: 'onboard-new-customer',
input: {
name: 'Jane Doe',
email: 'jane.doe@example.com',
company: 'Acme Inc.',
},
});
// The service handles all the underlying atomic actions
// and returns a simple, high-level result.
console.log(newCustomer);
// { success: true, customerId: 'cust_xyz_789', status: 'OnboardingInitiated' }
"Can't I just build this with a serverless function and an API gateway?"
While you could, service.do is a higher-level abstraction designed specifically for business logic and workflow automation. It provides critical infrastructure out of the box that you would otherwise have to build and maintain yourself.
Atomic actions give you reliability at a granular level. Agentic workflows allow you to create powerful, intelligent automations. But service.do is what lets you productize that power.
It represents the ultimate expression of Business-as-Code: transforming your operational logic from an internal cost center into a scalable, secure, and potentially profitable asset. You're no longer just building workflows; you're building Services-as-Software.
Ready to package your complex workflows into powerful API services? Explore what you can build with action.do and service.do today.