Developer Guide: Hooks, Filters, and the REST API

Krom Automation is built on standard WordPress patterns throughout- Action Scheduler for background jobs, $wpdb with prepared statements for database writes, WordPress nonces and manage_options capability for REST API authentication, and ReactFlow for the visual canvas.

If you know WordPress development, Krom Automation’s internals will feel familiar.

This guide covers how to interact with Krom Automation programmatically, trigger workflows from external code, and extend the plugin with custom triggers and actions.

Architecture overview #

Krom Automation follows a Trigger → Engine → Action pattern with full async support.

When a WordPress hook fires and matches a Krom Automation trigger, the trigger collects its data payload and passes it to the execution engine. The engine creates an Action Scheduler job with the workflow configuration and the trigger data. That job runs in the background — completely outside the web request that caused the trigger to fire.

Each action step runs independently within the job. A failing step logs its error and passes execution to the next step. The workflow does not crash on a single step failure.

Merge tag resolution and condition evaluation both happen at execution time, using the live trigger data payload. Nothing is resolved at workflow save time.

Database tables #

Krom Automation creates 8 custom tables on activation. The table prefix matches your WordPress $table_prefix setting.

TablePurpose
{prefix}krom-automation_logsLegacy execution log, one row per workflow run
{prefix}krom-automation_runsRun-once enforcement — records which entities have already triggered each workflow
{prefix}krom-automation_executionsModern execution tracking with unique execution IDs
{prefix}krom-automation_execution_stepsPer-step status, input, and output data for each execution
{prefix}krom-automation_stats_dailyPre-aggregated daily analytics data
{prefix}krom-automation_entity_logEntity-level automation event timeline
{prefix}krom-automation_variablesPersistent per-workflow variable storage
{prefix}krom-automation_approvalsHuman approval step tokens and state

All writes to these tables use $wpdb with prepared statements. Do not write directly to these tables from external code — use the REST API or PHP action hooks to interact with Krom Automation data cleanly.

Scheduled tasks #

Krom Automation registers two recurring WordPress Cron jobs:

HookFrequencyPurpose
krom-automation_daily_cleanupDailyDeletes execution logs older than the configured retention period
krom-automation_hourly_health_checkHourlyIdentifies and flags stuck or long-running executions

You can inspect and manage these using WP Crontrol or any WordPress cron management plugin. Do not remove or reschedule these hooks — they’re required for correct operation.


REST API #

The full REST API reference is in the REST API Reference doc. This section covers developer-specific use cases.

Authentication

All API endpoints require a WordPress user with the manage_options capability. For server-to-server requests, use WordPress Application Passwords (Dashboard > Users > Edit User > Application Passwords).

Authorization: Basic base64(username:application_password)

The exception is the public approval endpoint (/krom-automation/v1/approval/{token}) and the incoming webhook receiver (/krom-automation/v1/webhooks/{token}) — both are intentionally public.

Triggering a workflow via the API

POST /wp-json/krom-automation/v1/workflows/{id}/run
Authorization: Basic {credentials}
Content-Type: application/json

{
  "context": {
    "user_email": "test@example.com",
    "first_name": "Jane",
    "order_total": 150
  }
}

The context object supplies trigger data for merge tag resolution. Any key in the context object becomes available as a merge tag in the workflow’s actions.

Running a simulation via the API

POST /wp-json/krom-automation/v1/simulate
Authorization: Basic {credentials}
Content-Type: application/json

{
  "workflow_id": 42,
  "context": {
    "user_email": "test@example.com",
    "first_name": "Jane"
  }
}

The simulation response returns per-step results without executing any real side effects. Use this in automated testing pipelines to validate workflow configurations after deployment.

Exporting and importing workflows

# Export
GET /wp-json/krom-automation/v1/workflows/{id}/export
Authorization: Basic {credentials}

# Import
POST /wp-json/krom-automation/v1/workflows/import
Authorization: Basic {credentials}
Content-Type: application/json

{
  "workflow": { ...exported JSON... }
}

The imported workflow arrives in Paused status. Use this pattern to automate workflow deployment across staging and production environments.

WordPress hooks #

Krom Automation exposes action and filter hooks at key points in the execution lifecycle. These are the primary extension points for custom development.

Action hooks

krom-automation_before_workflow_execute Fires before a workflow execution begins. Receives the workflow ID and the trigger data payload.

add_action( 'krom-automation_before_workflow_execute', function( $workflow_id, $trigger_data ) {
    // Log or modify behaviour before execution starts
}, 10, 2 );

krom-automation_after_workflow_execute Fires after a workflow execution completes (whether successful or failed). Receives the workflow ID, trigger data, and the execution result object.

add_action( 'krom-automation_after_workflow_execute', function( $workflow_id, $trigger_data, $result ) {
    // Post-execution logging, notifications, etc.
}, 10, 3 );

krom-automation_before_action_execute Fires before each individual action step runs. Receives the action type, the action configuration, and the current execution context.

add_action( 'krom-automation_before_action_execute', function( $action_type, $config, $context ) {
    // Inspect or log individual steps before they run
}, 10, 3 );

krom-automation_after_action_execute Fires after each individual action step completes. Receives the action type, configuration, context, and the step result.

add_action( 'krom-automation_after_action_execute', function( $action_type, $config, $context, $result ) {
    // React to step outcomes
}, 10, 4 );

Filter hooks

krom-automation_trigger_data Filters the data payload collected by a trigger before it’s passed to the execution engine. Use this to add custom fields to an existing trigger’s data.

add_filter( 'krom-automation_trigger_data', function( $data, $trigger_id ) {
    if ( $trigger_id === 'user_registered' ) {
        $data['custom_field'] = get_user_meta( $data['user_id'], 'my_custom_meta', true );
    }
    return $data;
}, 10, 2 );

krom-automation_merge_tag_value Filters the resolved value of a specific merge tag. Use this to transform or override a tag’s value before it’s injected into an action field.

add_filter( 'krom-automation_merge_tag_value', function( $value, $tag, $context ) {
    if ( $tag === 'first_name' && empty( $value ) ) {
        return 'Friend'; // Fallback value when first_name is empty
    }
    return $value;
}, 10, 3 );

krom-automation_condition_result Filters the boolean result of a condition evaluation. Rarely needed, but available for advanced conditional logic overrides.

add_filter( 'krom-automation_condition_result', function( $result, $condition, $context ) {
    // Override condition results based on custom logic
    return $result;
}, 10, 3 );

Registering a custom trigger #

Custom triggers integrate into Krom Automation’s trigger registry and appear in the trigger selection panel on the canvas. They fire on a standard WordPress hook and expose data fields for use as merge tags.

add_filter( 'krom-automation_register_triggers', function( $triggers ) {
    $triggers['my_custom_trigger'] = [
        'id'          => 'my_custom_trigger',
        'label'       => 'My Custom Event',
        'description' => 'Fires when my custom event occurs.',
        'category'    => 'custom',
        'hook'        => 'my_plugin_custom_hook',
        'fields'      => [
            [
                'key'   => 'custom_id',
                'label' => 'Custom ID',
                'type'  => 'number',
            ],
            [
                'key'   => 'custom_email',
                'label' => 'Email',
                'type'  => 'email',
            ],
        ],
        'data_callback' => function( $hook_args ) {
            // Transform hook arguments into the trigger data array
            return [
                'custom_id'    => $hook_args[0],
                'custom_email' => $hook_args[1],
            ];
        },
    ];
    return $triggers;
} );

Once registered, my_custom_trigger appears in the trigger panel and its fields ({{custom_id}}, {{custom_email}}) are available as merge tags throughout the workflow.

Registering a custom action #

Custom actions appear in the action selection panel and execute custom PHP logic when reached during workflow execution.

add_filter( 'krom-automation_register_actions', function( $actions ) {
    $actions['my_custom_action'] = [
        'id'          => 'my_custom_action',
        'label'       => 'My Custom Action',
        'description' => 'Does something custom.',
        'category'    => 'custom',
        'fields'      => [
            [
                'key'        => 'target_id',
                'label'      => 'Target ID',
                'type'       => 'text',
                'required'   => true,
                'merge_tags' => true,
            ],
        ],
        'handler' => function( $config, $context ) {
            // $config contains the resolved field values
            // $context contains the full execution context including all merge tag values
            $target_id = $config['target_id'];

            // Your custom logic here
            $result = my_plugin_do_something( $target_id );

            if ( is_wp_error( $result ) ) {
                return new WP_Error( 'my_custom_action_failed', $result->get_error_message() );
            }

            return [ 'success' => true, 'result' => $result ];
        },
    ];
    return $actions;
} );

Return a WP_Error from the handler to mark the step as failed in the execution log. Return any non-error value for a successful step.

Dependencies #

Krom Automation’s frontend is built on React via @wordpress/element. The workflow canvas uses ReactFlow with dagre and elkjs for automatic layout. State is managed with Zustand. Charts use recharts. These are all bundled with the plugin — you do not need to enqueue them separately.

Backend execution uses Action Scheduler, which is included in the plugin’s vendor directory. If WooCommerce is also active and ships its own copy of Action Scheduler, WordPress’s standard library loading order handles the version conflict correctly.

DependencyVersion bundled
Action SchedulerBundled
ReactFlowBundled
ZustandBundled
dagre / elkjsBundled
rechartsBundled
react-router-domv6, bundled

Contributing and reporting bugs #

Krom Automation is developed by wpRigel. To report a bug or request a feature:

When reporting a bug, include your Krom Automation version, PHP version, WordPress version, the error message from the execution log, and a description of the workflow that’s causing the issue.

What are your feelings

Updated on July 14, 2026