---
title: "Developers"
description: "How the relay works, the capabilities, a PHP and JavaScript example, the extension API ShopSocket is built on, and links to every reference."
url: https://wpsignal.io/developers/
---

# Realtime on every site you build.

WPSignal is a hosted WebSocket relay for WordPress. Publish an event from any action hook with one PHP call and every browser on the site hears it within milliseconds. No server to run, no polling to tune, and event payloads are encrypted before they leave WordPress.

[Read the docs](https://wpsignal.io/docs/getting-started/) [Open the Explorer](https://wpsignal.io/docs/explorer/) [GitHub](https://github.com/wpsignal/wordsocket)

## Three hops, one connection

1.  ### 1. WordPress publishes

    A trigger on any action hook, or one WPS::publish() call, sends an HMAC-signed POST to the relay. The payload is encrypted before it leaves WordPress.

2.  ### 2. The relay fans out

    WPSignal delivers the event to every browser subscribed to that site's channels, over WebSocket with SSE as the fallback. Tokens decide who may read and write which channels.

3.  ### 3. The browser reacts

    WordSocket's client holds one connection per page and dispatches a native CustomEvent per event. Listen with plain JavaScript or any framework.

## Example

## Readable, developer focused API

Publish on any WordPress action hook using the fluent builder API. Add a condition, custom channel, or transform the payload: all optional.

## Listen for events

The browser client auto-connects and dispatches native `CustomEvent`s, listen with plain JavaScript or integrate with any frontend framework.

[See the full guide](https://wpsignal.io/docs/getting-started/)

```php
add_action('wpsignal_loaded', function () {
  WPS::trigger('order.status_changed')
    ->on('woocommerce_order_status_changed', 10, 3)
    ->channel('events')
    ->data(
      fn ($order_id, $old_status, $new_status) => [
        'order_id' => $order_id,
        'old_status' => $old_status,
        'new_status' => $new_status,
        'total' => wc_get_order($order_id)->get_total(),
      ])
    ->register();
});
```

```js
WPS.on('order.status_changed', (data) => {
  const {
    order_id,
    new_status,
    total
  } = data;
  triggerFlashNotification(order_id, new_status, total);
});
```

## Built for WordPress developers

-   ### WebSocket-first

    Persistent WebSocket connections with Server-Sent Events as automatic fallback. Keepalive pings every 20 seconds.

    WP SITE PUBLISH RELAY WPSignal CLIENT CLIENT CLIENT

-   ### HMAC-signed publishes

    Every event is signed with SHA-256 HMAC. Timestamp replay protection and per-site rate limiting built in.

    PAYLOAD TIMESTAMP replay guard · SITE\_SECRET HMAC SHA-256 a3f7 9c1e b82d SIG

-   ### Fluent trigger API

    Attach events to any WordPress action hook with a builder: channel, payload, condition and more, in one chain.

    WP·HOOK CONDITION .when() DATA·BUILDER TRIGGER .register() events post. updated PUBLISH

-   ### Blind relay encryption

    WordSocket encrypts event payloads with AES-256-GCM before they leave WordPress, on HTTPS and plain HTTP sites alike, so WPSignal relays ciphertext it cannot read.

    PLAINTEXT RAND·IV 12 bytes ENCRYPT·KEY AES·256 GCM dGhp c2lz dGVz CIPHER

-   ### Per-site isolation

    Each WordPress site gets its own site key, publish secret and token secret. Channels are namespaced per site and enforced by the relay.

    SITE·A SITE·B SITE·C RELAY WPSignal site:a events site:b events site:c events

-   ### Explorer

    Built-in admin page showing connection status, live event log, publish form, and token inspector for instant debugging.

    WP·ADMIN CONNECTED EXPLORER post.updated 14ms order.paid 6ms user.login 11ms comment.new 2ms PUBLISH events post.updated LIVE 1 client · 1 ch TOKEN site\_id channels exp EVENTS post.updated order.paid user.login

## Build on WordSocket

ShopSocket is built on nothing the public API does not offer. An extension reserves a channel namespace with its own read and write grants, publishes from PHP, holds connection-scoped presence from the browser, and adds a card or a whole tab to WordSocket's settings page. One connection per page, shared by everything on it.

[Extension API reference](https://wpsignal.io/docs/php-api/#extension-api) and the [extensions repository](https://github.com/wpsignal/wordsocket-extensions), where ShopSocket's source is the worked example.

```php
add_action('wpsignal_loaded', function () {
  $wps   = WPS::instance();
  $staff = 'manage_woocommerce';

  // Staff read it, only PHP writes to it.
  $wps->channels()->reserve('shop:orders', $staff, '__return_false');

  // Every shopper announces presence, only staff may listen.
  $wps->channels()->reserve('shop:carts', $staff, '__return_true');

  // A card on WordSocket's Extensions tab.
  $wps->extensions()->register('my-extension', [
    'title'    => 'My Extension',
    'version'  => '1.0.0',
    'docs_url' => 'https://example.com/docs',
    'file'     => plugin_basename(__FILE__),
  ]);
});

WPS::publish('shop:orders:feed', 'order.placed', ['id' => $order_id]);
```

```js
// Who is here right now; gone the instant the tab closes.
WPS.setPresence('shop:carts:live', { cart: cartId });

// Staff side: joins, leaves, and a sync on subscribe.
WPS.on('wps.presence', (data, channel) => {
  if (!WPS.onChannel(channel, 'shop:carts:live')) return;
  render(data.action, data.id, data.state, data.members);
});
```

```js
// Your own tab on WordSocket's settings page (0.28+).
window.wordsocket.registerTab({
  name: 'my-extension',
  title: 'My Extension',
  render: SettingsTab,
});
```

## Documentation

-   [**Getting Started** From a fresh install to a live browser event in under five minutes.](https://wpsignal.io/docs/getting-started/)
-   [**PHP API** The WPS facade, the trigger builder, the extension API, filters, actions and constants.](https://wpsignal.io/docs/php-api/)
-   [**JS API** window.WPS: subscribe, publish, presence, handler types, connection state and DOM events.](https://wpsignal.io/docs/js-api/)
-   [**REST API** The relay's HTTP surface with cURL examples: publish, stats, WebSocket, SSE, dashboard and admin.](https://wpsignal.io/docs/api-reference/)
-   [**Explorer** Register a site, connect and publish against the live API from the browser.](https://wpsignal.io/docs/explorer/)

## Push your first event

Connect a site and see an event land in the Explorer in minutes.

[Get started](https://api.wpsignal.io/dashboard/signup) [Getting started guide](https://wpsignal.io/docs/getting-started/)
