Workflow Handlers Reference
Catalogue of core workflow action handlers registered by the delivered engine.
How handlers are registered
WorkflowServiceProvider binds WorkflowHandlerRegistry as a singleton and
registers every core typed handler on boot. Plugins add handlers through
PluginRegistrar::workflowHandler() and cannot use an unprefixed core
identifier. register() refuses to overwrite an existing identifier.
Each registration stores a declaration with type, version, configuration
schema, input/output contracts, capabilities, retry flags, optional
subject policy, outcomes, sensitive_fields, and palette category, icon, and colour metadata. The workflow service
principal must hold every declared capability at execution time; a missing
capability fails the attempt rather than widening access.
The public handler contract is name(), description(), group(),
configSchema(), outputs(), and execute(). Identity lives on the
registry, not the class. See the
Workflow Handler Registry
contract page.
Core typed handlers
Sourced from each handler's IDENTIFIER, name(), description(), and
group(), plus the declaration registered in WorkflowServiceProvider.
| Identifier | Name | Group | Capability | Outcomes | Subject policy |
|---|---|---|---|---|---|
context.set |
Set context | Logic | none | continue_with_output, halt_successfully, failure | not declared |
approvals.request |
Request approval | Approvals | none | suspend_with_correlation, failure | required; not consequential; halt if unavailable |
log |
Log | Logic | none | continue_with_output, halt_successfully, failure | not declared |
activities.create |
Create activity | Activities | activities.create |
continue_with_output, halt_successfully, failure | required; not consequential; halt if unavailable |
communications.send |
Send customer communication | Communications | notifications.manage |
continue_with_output, halt_successfully, failure | required; not consequential; halt if unavailable |
notifications.dispatch_internal |
Dispatch internal notification | Notifications | notifications.manage |
continue_with_output, halt_successfully, failure | required; consequential; halt if unavailable |
event.fire |
Fire event | Logic | none | continue_with_output, halt_successfully, failure | not declared |
external.http |
Call external HTTP endpoint | External | external.http |
continue_with_output, halt_successfully, failure | optional; skip if unavailable |
webhook.signed |
Send signed webhook | Webhooks | external.http, integrations.credentials.use |
continue_with_output, failure | optional; skip if unavailable |
rentals.change_status |
Change rental status | Rentals | rentals.edit |
continue_with_output, halt_successfully, failure | required; consequential; halt if unavailable |
rentals.convert_to_order |
Convert rental to order | Rentals | rentals.edit |
continue_with_output, halt_successfully, failure | required; consequential; halt if unavailable |
rentals.allocate_asset |
Allocate rental asset | Rentals | rentals.edit |
continue_with_output, halt_successfully, failure | required; consequential; halt if unavailable |
rentals.quick_allocate |
Quick allocate rental assets | Rentals | rentals.edit |
continue_with_output, halt_successfully, failure | required; consequential; halt if unavailable |
documents.generate |
Generate rental document | Documents | documents.create |
continue_with_output, halt_successfully, failure | required; consequential; halt if unavailable |
invoices.generate_from_rental |
Generate rental invoice | Invoices | invoices.create |
continue_with_output, halt_successfully, failure | required; consequential; halt if unavailable |
invoices.issue |
Issue invoice | Invoices | invoices.issue |
continue_with_output, failure | required; consequential; halt if unavailable |
repairs.create |
Create repair | Repairs | repairs.create |
continue_with_output, failure | required; consequential; halt if unavailable |
assignments.create |
Create resource assignment | Scheduling | resource-assignments.create |
continue_with_output, failure | required; consequential; halt if unavailable |
exports.start |
Start export | Exports | exports.create |
continue_with_output, halt_successfully, failure | required for effect provenance; consequential; halt if unavailable |
What each handler does, in the handler's own words:
- Set context — Set declared literal values in the mutable workflow vars context.
- Request approval — Pause this workflow until its shared approval request is approved.
- Log — Write bounded, redacted operational evidence to the workflow outcome.
- Create activity — Create an audited activity for the workflow subject.
- Send customer communication — Send one attachment-free, audited customer communication for the workflow subject.
- Dispatch internal notification — Dispatch one configured operational notification to active internal recipients.
- Fire event — Emit one registered workflow custom event with a literal JSON payload.
- Call external HTTP endpoint — Call an approved HTTPS endpoint with bounded retries, redirects, payloads, and redacted output. Sensitive fields:
configuration.body,response.body. - Send signed webhook — Send a bounded JSON webhook with a stable delivery identity and HMAC signature. Sensitive fields:
configuration.payload,response.body. - Change rental status — Move the workflow rental to another selectable status in its current state.
- Convert rental to order — Convert the workflow rental through the guarded quote-to-order action.
- Allocate rental asset — Allocate one barcoded asset to a line item in the workflow rental.
- Quick allocate rental assets — Atomically allocate an ordered batch of barcoded assets to the workflow rental.
- Generate rental document — Generate one configured document for the workflow rental subject.
- Generate rental invoice — Generate one configured standard invoice for the workflow rental subject. The supplied workflow principal must currently have access to its warehouse before configuration validation or completed effect-receipt reuse. The handler uses that explicit principal; an authenticated request user does not supply missing workflow authority.
- Issue invoice — Finalise a draft using the existing invoice issue action, including its money evidence and posting guards. An invoice subject selects itself; a rental subject selects its only draft or the configured
invoice_id. A configured invoice must belong to that rental. Multiple drafts require an explicit ID. Customer delivery is held. Completed workflow receipts replay the original result without another posting. - Create repair — Raise a repair through
RaiseRepair, preserving reason-list, custom-field, conflict and demand validation. Configurereason_id,priority(low,normal,high,urgent), optionalnotesandquantity(default1.00). The asset is the subject or itsasset_id; an optionalasset_pathreads the execution context and must match that asset. Priority is retained in notes because repairs have no priority column. Workflow repairs refuse existing barcoded asset holds; an authenticated operator cannot lend shortage-override permission to a workflow step. - Create resource assignment — Schedule
accountcrew or avehiclefor the rental subject throughCreateResourceAssignment, retaining resource eligibility, window, conflict, billing and plugin guards. Configureresource_type,resource_id, optionalstarts_at,ends_at, andnotes. Omitted window bounds inherit the rental window. The rental and resource are constrained by delegated warehouse scope. - Start export — Queue one explicitly scoped model export and return its durable status reference. Its configuration controls source, filters, columns, and warehouse; the required live workflow subject supplies consequential effect-receipt provenance, including when an effect context is already supplied.
Retry: every typed core handler declares idempotent: true. Automatic retry
is enabled and marked safe for all except context.set, approvals.request,
and log, which set automatic_retry and automatic_retry_safe to false.
Legacy compatibility entry
WorkflowServiceProvider also calls registerLegacy() for
ExportWorkflowAction under identifier export. That entry is a
compatibility action, not a typed WorkflowHandler. New authoring should
use exports.start.
Suspensions and resume
approvals.request returns suspend_with_correlation and parks the run
until the shared approval request is settled. Other correlated
suspensions can be resumed by an external caller at
POST /api/v1/workflow-resumes (api.v1.workflow-resumes.store). See
Workflow Operations and
Workflow Triggers & Conditions.
Libraries and simulation
WorkflowEventLibrary groups every workflow-visible event by business area,
including unavailable triggers. Triggerable events sort first; unavailable
entries remain disabled. Unknown extension families appear under Other.
WorkflowStepLibrary reads palette metadata from handler declarations, with
built-in condition, delay, and halt kinds under Control. The API catalogue
uses the same metadata. Legacy export remains outside the authoring palette.
Every typed core handler implements simulate() for draft dry runs. The new
invoice, repair and assignment simulations return declared sample references
without writes, posting, scheduling, demand changes or outbound delivery.
An invoices.send handler is not registered. The installed billing delivery
path requires its original posting intent and user delivery authority; the
approved-draft send action is human-only. Neither is a delegated workflow
invoice-send action. A future adapter must preserve the recorded approval,
recipient authority and durable delivery identity rather than enqueueing an
unapproved billing email.