Creating Flows
Define a flow in YAML, run one command, and it exists in ServiceNow.
flowctl --instance https://myco.service-now.com \ --create my_flow.yaml \ --client-id $SN_CLIENT_ID \ --client-secret $SN_CLIENT_SECRETMinimal Flow
Section titled “Minimal Flow”schema: nebulaname: Hello World Flowtype: flowtrigger: type: record_created table: incidentsteps: - action: log inputs: message: "A new incident was created: $trigger.current.number"Dry Run
Section titled “Dry Run”Preview what the tool will do without changing anything in ServiceNow:
flowctl --instance https://myco.service-now.com \ --create my_flow.yaml --dry-runPrints every API call that would be made, with full payloads.
Flow Structure
Section titled “Flow Structure”Every YAML file has these sections:
schema: nebula # Schema versionname: "My Flow" # Requiredtype: flow # flow or subflow (default: flow)status: draft # draft or published (default: draft)run_as: system # system or user (default: system)access: public # public or package_private (default: public)
trigger: # Required for flows, not allowed for subflows type: record_created table: incident
inputs: [] # Subflow input parametersoutputs: [] # Subflow output parametersvariables: [] # Scratch variables
steps: # Required - action: lookup_record inputs: table: incidentSee the Schema Overview for the full field reference.
Action Steps
Section titled “Action Steps”Action steps call built-in ServiceNow actions:
- action: lookup_record name: Find the Caller inputs: table: sys_user conditions: "sys_id=$trigger.current.caller_id"Common actions: lookup_record, create_record, update_record, delete_record, send_email, send_notification, log, run_script.
Subflow Steps
Section titled “Subflow Steps”Call another subflow by its sys_id:
- subflow: abc123def456abc123def456abc123de name: Notify Team inputs: incident_number: $trigger.current.numberLogic Steps
Section titled “Logic Steps”Control flow with conditions, loops, and error handling:
- if: "$trigger.current.priority = 1" then: - action: send_email inputs: to: oncall@example.com subject: "P1 Incident: $trigger.current.number" body: "A P1 incident has been created." else: - action: log inputs: message: "Non-P1 incident, skipping notification."See Step Types for all available logic steps (for_each, parallel, try/catch, etc.).
Publishing
Section titled “Publishing”Set status: published to create and publish in one step:
status: publishedThe tool handles the SN compilation pipeline automatically — the same mechanism Flow Designer’s “Publish” button uses.
Realistic Example
Section titled “Realistic Example”schema: nebulaname: Incident Auto-Assignmenttype: flowstatus: draftdescription: Assigns new P1 incidents to the on-call group.run_as: systempriority: HIGH
trigger: type: record_created table: incident
variables: - name: assigned_group type: string
steps: - action: lookup_record id: find_group name: Find On-Call Group inputs: table: sys_user_group conditions: "name=On-Call Support"
- if: "$trigger.current.priority = 1" then: - action: update_record name: Assign to On-Call inputs: table: incident values: assignment_group: $find_group.record.sys_id - action: send_email inputs: to: $find_group.record.email subject: "P1: $trigger.current.short_description" body: "A new P1 incident requires attention." else: - action: log inputs: message: "Non-P1 incident, no auto-assignment."The web UI and REST API are available on the hosted version at flowctl.sh.