Main Header

Capturing Events with sp_capture()

Updated on July 30, 2026

SignalPress gives WordPress one primary API for sending signals: sp_capture(). A signal is a structured alert or activity update — routed to Slack, Email, PostHog, Local, or any other configured integration. Call it from PHP when you want to send a signal and optionally inspect per-service results.

If you have not installed SignalPress yet, start with Setup & Activating SignalPress. For a first admin test without code, try Your First Connection Test. To compose calls interactively, use sp_capture Builder.

Basic capture

PHP

$results = sp_capture(
	'checkout_completed',
	[
		'order_id' => 123,
		'total'    => 49.95,
	],
	[
		'distinct_id' => 'customer-42',
	]
);

sp_capture() accepts three arguments:

  1. Event name — normalized with sanitize_key()
  2. Data — associative array of event properties
  3. Options — optional context (project, source, services, identity fields, and more) — Event Context and Options

By default, a signal is offered to every active, enabled, and configured integration. To limit destinations, pass a services array in the options — for example, send a signal only to Slack or only to Email. See Service Targeting.

Broadcast vs targeted delivery

PHP

sp_capture(
	'backup_failed',
	[
		'title'   => 'Backup failed',
		'message' => 'The nightly database backup could not be completed.',
	],
	[
		'source'   => 'backup-worker',
		'services' => [ 'pushover' ],
	]
);

This sends a signal to Pushover only.

  • Omit services — broadcast the signal to every eligible integration
  • Set services — send the signal only to listed service IDs
  • Empty services array — intentionally send nowhere

Invalid service IDs or malformed options return WP_Error. Each integration may still apply its own routing rules after targeting.

Lower-level API

The original four-argument function remains available:

PHP

signalpress_capture( $event_name, $properties, $context, $services );

New code should prefer sp_capture( $name, $data, $options ) for clarity. The same options work from JavaScript through JavaScript capture.

The third context argument to signalpress_capture() may be a string — it is treated as the source value. The Test Shortcode uses this form:

PHP

signalpress_capture( 'signalpress_test', $properties, 'shortcode:signalpress_test' );

When delivery does not run

  • Event delivery unchecked in SignalPress → Settingssp_capture() returns an empty array (not an error).
  • Hub operation mode set to read-only or disabled — returns WP_Error with a remote message.
  • Validation failure — returns WP_Error and fires signalpress/rejected. See Event Context and Options.

After successful dispatch, the signalpress/captured action runs with the event object and per-service results. On Tier 2 sites with the delivery queue enabled, remote services log queued immediately and dispatched when the worker completes — handoff is asynchronous even though sp_capture() returns right away.

Action-based capture

Decouple the caller with a WordPress action:

PHP

do_action(
	'signalpress/capture',
	'checkout_completed',
	[ 'order_id' => 123 ],
	[ 'distinct_id' => 'customer-42' ]
);

Pass an optional fourth argument — an array of service IDs — to target destinations from the action:

PHP

do_action( 'signalpress/capture', 'order_shipped', $data, $context, [ 'slack', 'email' ] );

Use this when a theme or plugin should fire an event without importing SignalPress helpers directly, as long as SignalPress is active. Wire capture from Loading SignalPress Safely rather than at file scope.

Tier 1+ sites can reshape payloads before dispatch with Hooks and Filters.

Return value

sp_capture() returns an array keyed by service ID. Values are true on successful handoff or WP_Error when that service rejected the event.

Check results when debugging integrations or building admin tools. Delivery log rows appear under each service’s Logs tab and on Recent Activity after capture — queued first when the durable queue is enabled, then dispatched or failed when the worker finishes. Without the queue, successful remote rows show dispatched with HTTP Status Async. Full column reference: Connection Tests and Delivery Log.