Skip to main content

Workflow DSL Reference

Pidima workflows can be written as YAML or JSON documents using the Business Workflow DSL. This format is designed to be human-readable and version-controllable while expressing complex business processes.

Standards & Influences

The Pidima Workflow DSL draws from established workflow and process modeling standards:

StandardInfluence on Pidima DSL
BPMN 2.0 (Business Process Model and Notation)Node types (tasks, decisions, events), gateway patterns, and process flow semantics
DMN (Decision Model and Notation)Business rules structure, decision tables, and condition expressions
CMMN (Case Management Model and Notation)Human task handling, case-based work, and discretionary activities
WS-BPEL (Web Services Business Process Execution Language)Process execution semantics and service orchestration patterns

Key Design Principles

  • Business-first vocabulary: Node names describe what happens ("Assess Eligibility") not how ("Call API")
  • Declarative rules: Business logic expressed as readable conditions, not code
  • Separation of concerns: Business workflow separate from technical integration details
  • Version control friendly: YAML/JSON format works with Git and standard diff tools
  • Human and machine readable: Clear enough for business analysts, precise enough for execution

Document Structure

Every workflow document follows this structure:

apiVersion: pidima.ai/v1
name: Workflow Name
description: What this workflow does

trigger:
# How the workflow starts

nodes:
# The steps in the workflow

connections:
# How steps connect to each other

API Version

All workflow documents must specify the API version:

apiVersion: pidima.ai/v1

Metadata

FieldRequiredDescription
nameYesDisplay name for the workflow
descriptionNoOne-sentence explanation of what the workflow does
tagsNoArray of tags for organization
versionNoSemantic version string

Trigger

The trigger defines how a workflow starts. Every workflow needs exactly one trigger.

Manual Trigger

The most common trigger type - a person starts the workflow by filling in a form:

trigger:
type: manual
name: Start Application
fields:
- name: applicant_name
type: string
required: true
description: Full legal name
- name: loan_amount
type: number
required: true
description: Requested loan amount in USD
- name: documents
type: array
description: Supporting documents

Field Types

TypeDescription
stringText value
numberNumeric value (integer or decimal)
booleanTrue/false value
objectStructured data
arrayList of values
anyAny type (avoid when possible)

Other Trigger Types

# Webhook trigger - starts from an external HTTP call
trigger:
type: webhook
name: API Request Received

# Event trigger - starts from a connected system event
trigger:
type: event
name: Jira Issue Created
connectionKey: jira-production

# Schedule trigger - starts on a cron schedule
trigger:
type: schedule
name: Daily Reconciliation
schedule: "0 6 * * *" # 6 AM daily

Node Types

Pidima supports six business node types:

TypePurpose
BUSINESS_STEPA unit of work that transforms the case
DECISIONA branching point based on conditions
HUMAN_TASKA person reviews, approves, or investigates
WAITThe process pauses for time or an event
ACTIONAn external system is called
ENDAn outcome the process finishes with

BUSINESS_STEP

The most common node type. Represents a meaningful unit of business work:

- id: assess_eligibility
type: BUSINESS_STEP
name: Assess Eligibility
purpose: Determine if the applicant meets basic requirements

inputs: [applicant_name, loan_amount]

parameters:
min_credit_score: 650
max_debt_ratio: 0.43

rules:
- id: CR1
name: Credit score check
priority: 1
condition: "credit_score >= min_credit_score"
outcome: PASS
- id: CR2
name: Debt ratio check
priority: 2
condition: "debt_ratio <= max_debt_ratio"
outcome: PASS
- id: CR3
name: Default rejection
priority: 99
condition: "true"
outcome: REJECT

outputs:
- name: eligibility_result
type: string
- name: rejection_reasons
type: array

DECISION

A branching point with explicit conditions:

- id: risk_routing
type: DECISION
name: Route by Risk Level
purpose: Direct the case based on assessed risk

inputs: [risk_score]

branches:
- id: high
label: High Risk
when: "risk_score >= 80"
- id: medium
label: Medium Risk
when: "risk_score >= 40 && risk_score < 80"
- id: low
label: Low Risk
isDefault: true

HUMAN_TASK

A step where a person must take action:

- id: manager_review
type: HUMAN_TASK
name: Manager Review
purpose: Senior approval for high-value requests

inputs: [request_details, assessment_summary]

outputs:
- name: decision
type: string
- name: comments
type: string

WAIT

Pauses the workflow for a specified time or event:

- id: cooling_period
type: WAIT
name: Regulatory Cooling Period
purpose: Wait for mandatory review period
waitFor: Regulatory cooling-off period
waitHours: 72

ACTION

Calls an external system:

- id: send_notification
type: ACTION
name: Send Approval Email
purpose: Notify the applicant of the decision

inputs: [applicant_email, decision, loan_amount]

tools:
- capability: send_email
connection: email-service
action: send_template

END

Terminates the workflow with an outcome:

- id: approved
type: END
name: Application Approved
purpose: The application has been approved
status: APPROVED

- id: rejected
type: END
name: Application Rejected
purpose: The application has been rejected
status: REJECTED

Connections

Connections define how nodes link together:

connections:
# Simple connection
- from: start
to: assess_eligibility

# Connection from a decision branch
- from: risk_routing
to: manager_review
branch: high

- from: risk_routing
to: auto_approve
branch: low
Start Node

The trigger implicitly creates a node with id start. Connect from start to your first business node.

Rules

Rules define the business logic within a step. They're evaluated in priority order:

rules:
- id: R1
name: High-value auto-reject
priority: 1
condition: "amount > 1000000 && !has_collateral"
outcome: REJECT

- id: R2
name: Standard approval
priority: 2
condition: "credit_score >= 700 && debt_ratio < 0.3"
outcome: APPROVE

- id: R3
name: Manual review required
priority: 99
condition: "true"
outcome: REVIEW

Condition Syntax

Conditions use a simple expression language:

OperatorMeaningExample
==Equalsstatus == 'active'
!=Not equalsregion != 'restricted'
>, >=Greater thanamount >= 1000
<, <=Less thanage < 18
&&Anda > 0 && b > 0
||Orstatus == 'a' || status == 'b'
!Not!is_blocked

Parameters

Parameters are the configurable values a business user can change:

parameters:
approval_threshold: 50000
max_processing_days: 5
allowed_regions: ["US", "CA", "UK"]
require_two_approvers: true

Use parameters in conditions by their name:

condition: "amount <= approval_threshold"

Operations

Operations define data transformations within a step:

operations:
- type: lookup
source: credit_bureau
query: "ssn = {{applicant_ssn}}"
into: credit_report

- type: calculate
expression: "income / monthly_debt"
into: debt_ratio

- type: transform
input: raw_documents
mapping:
type: "doc.documentType"
date: "doc.uploadDate"
into: processed_documents

Tools

Tools bind external capabilities to a step:

tools:
- capability: fetch_credit_score
connection: experian
action: get_consumer_report
args:
ssn: "{{applicant_ssn}}"
report_type: "full"

Required Systems

Declare external systems the workflow needs:

requiredSystems:
- key: crm
kind: SALESFORCE
purpose: Customer record management
- key: credit
kind: REST_API
purpose: Credit bureau integration
suggestedBaseUrl: https://api.creditbureau.example.com

Complete Example

apiVersion: pidima.ai/v1
name: Loan Application Review
description: Process and decide on loan applications

trigger:
type: manual
name: New Application
fields:
- name: applicant_name
type: string
required: true
- name: loan_amount
type: number
required: true
- name: loan_purpose
type: string

nodes:
- id: initial_assessment
type: BUSINESS_STEP
name: Initial Assessment
purpose: Gather credit data and assess basic eligibility
inputs: [applicant_name, loan_amount]
parameters:
min_credit_score: 620
rules:
- id: IA1
name: Minimum credit
priority: 1
condition: "credit_score >= min_credit_score"
outcome: ELIGIBLE
- id: IA2
name: Below minimum
priority: 2
condition: "true"
outcome: INELIGIBLE
outputs:
- name: assessment_result
type: string
- name: credit_score
type: number

- id: risk_decision
type: DECISION
name: Risk Level Routing
purpose: Route based on loan amount and credit
inputs: [loan_amount, credit_score]
branches:
- id: auto_approve
label: Auto Approve
when: "loan_amount < 10000 && credit_score > 750"
- id: standard
label: Standard Review
when: "loan_amount < 50000"
- id: senior
label: Senior Review
isDefault: true

- id: senior_review
type: HUMAN_TASK
name: Senior Underwriter Review
purpose: Manual review for high-value applications
inputs: [applicant_name, loan_amount, credit_score]
outputs:
- name: decision
type: string
- name: conditions
type: array

- id: approved
type: END
name: Approved
purpose: Application approved
status: APPROVED

- id: rejected
type: END
name: Rejected
purpose: Application rejected
status: REJECTED

connections:
- from: start
to: initial_assessment
- from: initial_assessment
to: risk_decision
- from: risk_decision
to: approved
branch: auto_approve
- from: risk_decision
to: senior_review
branch: senior
- from: senior_review
to: approved
- from: senior_review
to: rejected

requiredSystems:
- key: credit_bureau
kind: REST_API
purpose: Credit score lookup

JSON Format

The same workflow can be written as JSON:

{
"apiVersion": "pidima.ai/v1",
"name": "My Workflow",
"trigger": {
"type": "manual",
"fields": [
{"name": "reference", "type": "string", "required": true}
]
},
"nodes": [
{
"id": "step1",
"type": "BUSINESS_STEP",
"name": "First Step",
"purpose": "Do the first thing",
"outputs": [{"name": "result", "type": "string"}]
},
{
"id": "done",
"type": "END",
"name": "Complete",
"status": "DONE"
}
],
"connections": [
{"from": "start", "to": "step1"},
{"from": "step1", "to": "done"}
]
}

Validation

The workflow editor validates your document as you type. Common issues include:

  • Missing required fields: name, trigger, at least one node
  • Invalid node references: Connections referencing non-existent node IDs
  • Missing END node: Every path must terminate at an END node
  • Invalid conditions: Syntax errors in rule conditions
  • Circular connections: Loops without proper exit conditions

Next Steps