Process step code guide
Document information
- Canonical URL:
/docs/02_automations-and-processflow/28_process-step-code-guide - Version:
2026-06-17 - Tags:
processflow,process-step-code,guides
Process step code lets you transform input, call platform services, and return structured output inside each ProcessFlow step. This guide explains the core execution contract, recommended service usage, and practical patterns you can reuse safely in production.
Understand the step contract
Each step receives data in process_input (a JSON object) and must return a JSON object — a plain JavaScript or TypeScript object. Legacy PHP steps used PHP arrays, which map to objects in JSON; do not return a bare array as your step result.
Returning a consistent shape keeps downstream steps predictable and makes failure handling easier to operate.
A practical success pattern is { success: true, data: { ... } } with only the fields the next step needs. The platform forwards the data object to the following step and to the process final_output, not the full wrapper.
A practical error pattern is { success: false, error: { code, message } }. The platform treats success: false as a failed step so dashboards, alerts, and retries can classify failures correctly.
type ProcessInput = {
customer_id?: string;
amount?: number;
};
type StepResult =
| { success: true; data: { customer_id: string; normalized_amount: number } }
| { success: false; error: { code: string; message: string } };
function normalizeOrder(input: ProcessInput): StepResult {
if (!input.customer_id) {
return {
success: false,
error: { code: "VALIDATION_ERROR", message: "customer_id is required" },
};
}
return {
success: true,
data: {
customer_id: input.customer_id,
normalized_amount: Number(input.amount ?? 0),
},
};
}Use platform services safely
Most production snippets combine tenant data access, secrets, connectors, and internal HTTP. In new JavaScript/TypeScript steps, prefer the tf namespace (tf.tenantDb, tf.connector, tf.api, tf.keystore, …). Legacy root globals (tenantDb, integration, api) remain for migrated snippets and are mirrored on tf.
See the Process sandbox tf API reference for the full capability matrix, tf.integration async patterns, and examples.
When a step calls external systems, validate required input first, load secrets from the keystore at runtime, and return stable error codes for non-2xx responses. This gives you reliable retries and clear incident triage.
type ApiResponse = { success: boolean; status_code: number; data?: { order_id?: string } };
async function createOrder(input: { customer_id?: string; amount?: number }) {
if (!input.customer_id) {
return { success: false, error: { code: "VALIDATION_ERROR", message: "customer_id is required" } };
}
const result = await tf.api.post("/api/v1/orders", {
customer_id: input.customer_id,
amount: Number(input.amount ?? 0),
}) as ApiResponse;
if (!result.success || !result.data?.order_id) {
return { success: false, error: { code: "ORDER_CREATE_FAILED", message: "Could not create order" } };
}
return { success: true, data: { order_id: result.data.order_id } };
}Trigger process execution through API
When you need to trigger or test a process from outside the editor, use the ProcessFlow API. Include the tenant header and authorization key so the request runs in the correct scope.
Use this request pattern for integration tests, external orchestrators, or webhook-driven entry points.
curl -X POST "https://<YOUR_DOMAIN>/api/v1/processflow?action=execute-process" \
-H "X-API-Key: <API_KEY>" \
-H "X-Tenant-ID: <TENANT_ID>" \
-H "Content-Type: application/json" \
-d '{
"process_id": "<PROCESS_ID>",
"input_data": {
"customer_id": "CUST_1024",
"amount": 149.95
},
"async": true
}'
{
"success": true,
"data": {
"queue_id": "q_7f3c2b19",
"status": "queued"
}
}
Keep snippets reliable in production
Reliable step code is small, explicit, and observable. Keep each step focused on one responsibility, avoid hidden side effects, and always return an object shape that downstream steps can trust.
Use stable error codes such as VALIDATION_ERROR, API_ERROR, and RESOURCE_ERROR so operations teams can filter logs and alerts consistently. For deeper debugging patterns and file-specific operations, continue with File operations and WebApp API usage guide.
This approach helps you build ProcessFlow automations that are easier to test, safer to run in multi-tenant environments, and faster to maintain as workflows grow.