Claude Skill

wp-presence-api

Implement or audit integrations with the experimental WordPress Presence API feature plugin 0.1.23. Covers the seven public PHP functions, post and admin rooms, the per-site wp_presence table and TTL, Heartbeat transport, REST read/write/delete/rooms endpoints, per-room capabilit

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download lonsdale201-wp-agent-skills-wordpress_wp-presence-api-52f6020.zip · 7 KB
Part of lonsdale201/wp-agent-skills — 226 skills

Install

skills CLI npx skills add https://github.com/Lonsdale201/wp-agent-skills/tree/main/wordpress/wp-presence-api
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lonsdale201-wp-agent-skills@llmmart
Git git clone https://github.com/Lonsdale201/wp-agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole lonsdale201/wp-agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

WordPress Presence API

Integrate with Presence API 0.1.23 as an experimental feature plugin, not as a WordPress 7.1 core API. It supplies awareness of active users and editors using a dedicated per-site table, a 60-second TTL, Heartbeat, REST, admin surfaces, and a small public PHP API. Pin and feature-detect the plugin; its 0.1.x contract may still change.

When to use this skill

  • Build who-is-online, active-editor, post-lock, or co-presence UI.
  • Review wp_get_presence(), wp_set_presence(), wp_presence_post_room(), presence-ping, wp_presence_editor_state, or /wp-presence/v1 code.
  • Add presence support to a custom post type.
  • Decide where to store high-frequency ephemeral state.
  • Audit Heartbeat load, room authorization, presence privacy, cleanup, or multisite behavior.

Establish the runtime contract first

Feature-detect a public function and avoid loading plugin internals yourself:

if ( ! function_exists( 'wp_get_presence' ) ) {
    return;
}

Presence API 0.1.23 requires WordPress 7.0+ and PHP 7.4+. WordPress 7.1 does not provide these functions or the wp_presence table by itself. Do not test only version_compare( get_bloginfo( 'version' ), '7.1', '>=' ).

Treat an experimental-plugin version constraint as a deliberate product decision. Fail softly when it is absent, and verify the installed source again before relying on signatures in a later 0.1.x release.

Use only the seven public PHP functions

The source explicitly marks these as its public contract:

Function Contract
wp_get_presence( $room, $timeout ) Return active entry objects for one room.
wp_set_presence( $room, $client_id, $state, $user_id ) Atomically upsert one (room, client_id) row.
wp_remove_presence( $room, $client_id ) Remove one client entry.
wp_remove_user_presence( $user_id ) Remove a user's entries across all rooms.
wp_can_access_presence_room( $room, $user_id ) Check the plugin's room access policy.
wp_presence_post_room( $post ) Return the canonical post room or false.
wp_presence_admin_room() Return the canonical admin/online room.

Everything after the public section in includes/functions.php is marked private even when it has a global wp_* function name. Do not depend on wp_get_active_rooms(), wp_get_presence_summary(), table/provisioning helpers, or cleanup internals.

The direct PHP write/remove functions are trusted server-side primitives. They do not reproduce the REST controller's room-length, payload, ownership, entry limit, or capability checks. Validate and authorize before calling them from any request handler.

Model rooms and authorization together

Core post types post and page opt in automatically. Add support to a custom post type during registration or afterwards:

register_post_type(
    'book',
    array(
        'show_ui'  => true,
        'supports' => array( 'title', 'editor', 'presence' ),
    )
);

$room = wp_presence_post_room( $book_id ); // postType/book:123 or false.

postType/{post_type}:{id} rooms require edit_post for that object. Other room strings, including admin/online, require only edit_posts. Therefore a custom room name is not a custom authorization boundary. Do not put data in a generic room when every user with edit_posts must not see it; enforce the narrower capability in your own server handler or use an object-backed room.

Presence is awareness, not authorization. Never grant locks, saves, or content access merely because a user has a presence entry.

Keep state ephemeral and bounded

$room      = wp_presence_post_room( $post_id );
$client_id = 'my-plugin-' . get_current_user_id();

if ( $room && current_user_can( 'edit_post', $post_id ) ) {
    wp_set_presence(
        $room,
        $client_id,
        array( 'mode' => 'reviewing' ),
        get_current_user_id()
    );
}

Use stable, namespaced client IDs. Store only small UI state, never secrets, tokens, unpublished content bodies, or durable workflow state. Entries expire from reads after the TTL and are later removed in bounded cron batches. TTL is not a delivery guarantee, logout is not guaranteed to run, and a crashed tab can remain visible until expiry.

The table is the correct architectural pattern for high-frequency awareness: it avoids repeatedly invalidating wp_options or object meta caches. It does not make every custom ephemeral feature a reason to depend on this plugin; use the public contract only when Presence API's room and capability model fit.

Use the REST contract safely

Authenticated endpoints are:

Method Route Purpose
GET /wp-presence/v1/presence Paginated entries for room.
POST /wp-presence/v1/presence Upsert room, client_id, and data.
DELETE /wp-presence/v1/presence Delete an owned entry; manage_options can delete any.
GET /wp-presence/v1/presence/rooms Paginated, access-filtered active rooms.
POST /wp-presence/v1/presence/screen-revisions/stale Bump an authorized screen revision.

Use wp.apiFetch in WordPress admin/editor JavaScript so the REST nonce and root middleware are applied. Respect pagination headers and request _fields when only user identity is needed. Responses use Cache-Control: no-store.

The 0.1.23 controller bounds room/client IDs to 191 characters, REST state to 10 KiB and three nested array levels, list pages to 100 rows, and active entries to 50 per user. It rejects an active client_id owned by a different user and restricts delete-by-client ownership. Do not clone these values into a competing endpoint; use the plugin route or implement an independently reviewed contract.

Read references/api-and-runtime.md before adding a REST client, custom room, screen-revision integration, or multisite dependency.

Integrate Heartbeat without multiplying traffic

The plugin enqueues WordPress Heartbeat and writes initial presence on eligible admin/front-end requests, then refreshes state through Heartbeat. The block editor can run Heartbeat faster than its normal 60-second interval for post locks. Do not add a second timer that posts the same state independently.

The shipped usePresenceUsers() React hook performs one REST read initially and on Heartbeat ticks, deduplicates by user ID, supports _fields, and can exclude the current user. In 0.1.23 it is shipped as source, not as a registered WordPress package or script handle. Do not deep-import another installed plugin's filesystem path at runtime. If a build deliberately vendors that experimental source, pin the plugin release and review license/update drift; otherwise implement a small wp.apiFetch consumer around the REST contract.

Treat collaboration hooks as advisory in 0.1.23

wp_presence_editor_state can enrich editor state. The plugin also declares wp_presence_collaboration_started and wp_presence_collaboration_ended. Do not use the latter actions for billing, durable workflow transitions, or exact participant lifecycle: in 0.1.23 threshold memory is a request-local static variable, so it does not persist a transition state across separate Heartbeat requests. Recompute current membership from the room for decisions and verify this implementation again after upgrading.

Test the whole lifecycle

  1. Absence of the feature plugin: integration fails softly.
  2. Supported and unsupported post types: room string versus false.
  3. Author can access own editable post but not a post they cannot edit.
  4. Generic custom room visibility for every edit_posts user.
  5. REST create/read/delete, ownership conflict, 191-character keys, oversized state, nested state, pagination, _fields, and Cache-Control: no-store.
  6. Two tabs for one user and two users in one room; close/crash/logout/TTL.
  7. Heartbeat active, slowed, suspended, and unavailable.
  8. Table missing during a front-end request: reads return empty and writes return false instead of causing SQL errors.
  9. Site activation, network activation, new-site creation, large network, cron cleanup, deactivation, and uninstall on a real multisite test network.
  10. Dynamic UI with keyboard focus, empty avatar alt text, live-region announcements, and reduced motion.

Critical rules

  • Presence API 0.1.23 is an experimental plugin, not WordPress 7.1 core.
  • Feature-detect it and use only the seven explicitly public PHP functions.
  • Keep capability checks at every write/read boundary; presence grants nothing.
  • Treat generic rooms as visible to all users with edit_posts.
  • Keep state small, non-secret, ephemeral, and retry-safe.
  • Reuse Heartbeat; do not add a competing polling loop.
  • Do not depend on private global helpers or exact internal table queries.
  • Do not treat collaboration threshold hooks as durable transition events.

Cross-references

  • Use wp-rest-api when implementing a separate custom endpoint.
  • Use wp-plugin-options-storage for the custom-table decision.
  • Use wp-plugin-cron for cleanup reliability and multisite scheduling.

References

Files (wp-agent-skills)
  • agents
    • openai.yaml 295 B
      interface:
        display_name: "WordPress Presence API"
        short_description: "Integrate the experimental Presence API safely"
        default_prompt: "Use $wp-presence-api to implement or audit this WordPress presence integration against feature plugin 0.1.23."
      
      policy:
        allow_implicit_invocation: true
      
  • references
    • api-and-runtime.md 5.7 KB
      # Presence API 0.1.23 API and runtime contract
      
      Read this reference when implementing an integration rather than only deciding
      whether the Presence API is relevant.
      
      ## Storage and return shape
      
      Each site owns a `{prefix}presence` table with:
      
      - numeric primary key `id`;
      - `room` and `client_id`, each `varchar(191)` and unique as a pair;
      - `user_id`;
      - JSON state in `longtext`;
      - UTC refresh time in `date_gmt`;
      - indexes for time, user, and room/time reads.
      
      `wp_get_presence()` returns objects with `room`, `client_id`, `user_id`,
      decoded array `data`, and `date_gmt`. The direct PHP API does not hydrate user
      display names or avatars. The REST representation adds `display_name` and
      `avatar_url` and supports `_fields`.
      
      The default TTL is `WP_PRESENCE_DEFAULT_TTL` (60 seconds). Define the constant
      before plugin load or filter `wp_presence_default_ttl`. Keep it positive and
      test it against actual Heartbeat intervals and background-tab suspension.
      
      ## REST enforcement
      
      The controller applies these 0.1.23 boundaries:
      
      - `room` and `client_id`: non-empty string, maximum 191 characters;
      - `data`: JSON object, maximum encoded size 10,240 bytes;
      - nested arrays: sanitized recursively to three levels;
      - state values: strings, integers, floats, booleans, and arrays only;
      - entry listing: `per_page` 1-100, default 100;
      - room listing: `per_page` 1-100, default 50;
      - active entries per user: maximum 50;
      - same active `(room, client_id)` owned by someone else: HTTP 409;
      - unavailable table on a write: HTTP 503;
      - every collection response: `X-WP-Total`, `X-WP-TotalPages`, and
        `Cache-Control: no-store`.
      
      Sanitized REST strings are preserved as data and must still be escaped for the
      eventual HTML, attribute, URL, or JavaScript output context.
      
      `GET`, `POST`, and `DELETE` all call `wp_can_access_presence_room()`. A post
      room maps to `user_can( $user_id, 'edit_post', $post_id )`; other rooms map to
      `edit_posts`. Delete additionally checks database ownership, except users with
      `manage_options` may remove another user's entry.
      
      ## Heartbeat behavior
      
      The plugin uses these principal server hooks:
      
      - `heartbeat_received` priority 9: update `admin/online`;
      - priority 10: update the post editor entry;
      - priority 11: bridge a core post-lock refresh when the editor ping was absent;
      - priority 12: compare stale-screen revisions.
      
      The ping asset is enqueued only for logged-in users with `edit_posts`; on the
      front end the admin bar must also be showing. It writes an initial entry in the
      page request to avoid a gap until the first Heartbeat tick. Editor client IDs
      use `editor-{user_id}` and the admin room uses `user-{user_id}`.
      
      Do not assume one entry per user. A user can occupy multiple rooms and clients;
      REST consumers should deduplicate by `user_id` when displaying people rather
      than connections.
      
      ## Screen revisions
      
      Classic settings, post, user, term, and comment screens are covered. Custom
      admin screens need both sides:
      
      1. filter `wp_presence_current_screen_key` to return a stable, non-empty key;
      2. after a successful REST/AJAX save, call the plugin's browser-side
         `wp.presence.markScreenStale( key )` surface when available.
      
      The REST route accepts lowercase letters, digits, slash, underscore, and
      hyphen after normalization and caps the key at 191 characters. Its permission
      callback maps known screen-key families to relevant object capabilities.
      Custom fallback revisions share a bounded 200-entry option; known object
      screens use object metadata or dedicated state instead.
      
      `wp_presence_screen_revision_bumped` receives the screen key, revision, and
      actor ID after a successful bump.
      
      ## Editor and collaboration extension points
      
      `wp_presence_editor_state` receives current state, post ID, and user ID. Add
      only bounded, non-secret, JSON-compatible values:
      
      ```php
      add_filter(
          'wp_presence_editor_state',
          static function ( array $state, int $post_id, int $user_id ): array {
              if ( current_user_can( 'edit_post', $post_id ) ) {
                  $state['my_plugin_mode'] = 'review';
              }
              return $state;
          },
          10,
          3
      );
      ```
      
      At 0.1.23, collaboration start/end threshold tracking uses a static variable
      inside `wp_presence_check_collaboration_threshold()`. That memory survives
      multiple calls only inside one PHP request. Normal Heartbeat transitions occur
      across requests, so do not interpret these actions as a durable or exactly-once
      session lifecycle. Query the room and make the downstream operation idempotent.
      
      ## Provisioning and cleanup
      
      Activation provisions the current site. Network activation iterates sites only
      when WordPress does not classify the network as large. New sites are provisioned
      after `wp_initialize_site`; missed/large-network sites reconcile on a real admin
      or CLI request. Front-end and AJAX request paths do not repeatedly run schema
      repair. Until provisioning succeeds, PHP reads return an empty array and writes
      return `false`.
      
      Cleanup runs through `wp_delete_expired_presence_data` on a custom one-minute
      WP-Cron interval. It selects and deletes bounded primary-key batches; the
      defaults are 1,000 rows per pass and 10 passes per invocation, filterable via
      `wp_presence_cleanup_batch_size` and `wp_presence_cleanup_max_passes`.
      
      Deactivation clears scheduled cleanup; uninstall drops each site's table and
      removes plugin revision/options/meta. Because WP-Cron is traffic-dependent,
      expiry filtering protects reads even when physical cleanup is delayed.
      
      ## Public documentation inconsistency
      
      At tag `v0.1.23`, `README.md` says “six public functions” and its code block
      lists six, while `includes/functions.php` explicitly says “Public API (7
      functions)” and additionally lists `wp_presence_admin_room()`. The function's
      docblock is not marked private. Treat the tagged source as authoritative for
      this snapshot, but recheck the upstream contract on the next release.
      
  • SKILL.md 10.6 KB
    ---
    name: wp-presence-api
    description: Implement or audit integrations with the experimental WordPress Presence API feature plugin 0.1.23. Covers the seven public PHP functions, post and admin rooms, the per-site wp_presence table and TTL, Heartbeat transport, REST read/write/delete/rooms endpoints, per-room capabilities and ownership, pagination and payload limits, post-type opt-in, usePresenceUsers source hook, stale-screen revisions, collaboration hooks, cleanup and multisite provisioning. Use for who-is-online, active-editor, post-lock, co-presence, Heartbeat, `wp_get_presence`, `wp_set_presence`, `wp-presence/v1`, or high-frequency ephemeral-state work. Do not confuse this experimental plugin with WordPress 7.1 core.
    license: GPLv2-or-later
    metadata:
      wp-skills-author: "Soczó Kristóf"
      wp-skills-contact: "mailto:lonsdale201@hotmail.com"
      wp-skills-plugin: "presence-api"
      wp-skills-plugin-version-tested: "0.1.23"
      wp-skills-wp-version-tested: "7.1"
      wp-skills-php-min: "7.4"
      wp-skills-last-updated: "2026-08-20"
    ---
    
    # WordPress Presence API
    
    Integrate with Presence API 0.1.23 as an experimental feature plugin, not as a
    WordPress 7.1 core API. It supplies awareness of active users and editors using
    a dedicated per-site table, a 60-second TTL, Heartbeat, REST, admin surfaces,
    and a small public PHP API. Pin and feature-detect the plugin; its `0.1.x`
    contract may still change.
    
    ## When to use this skill
    
    - Build who-is-online, active-editor, post-lock, or co-presence UI.
    - Review `wp_get_presence()`, `wp_set_presence()`, `wp_presence_post_room()`,
      `presence-ping`, `wp_presence_editor_state`, or `/wp-presence/v1` code.
    - Add presence support to a custom post type.
    - Decide where to store high-frequency ephemeral state.
    - Audit Heartbeat load, room authorization, presence privacy, cleanup, or
      multisite behavior.
    
    ## Establish the runtime contract first
    
    Feature-detect a public function and avoid loading plugin internals yourself:
    
    ```php
    if ( ! function_exists( 'wp_get_presence' ) ) {
        return;
    }
    ```
    
    Presence API 0.1.23 requires WordPress 7.0+ and PHP 7.4+. WordPress 7.1 does
    not provide these functions or the `wp_presence` table by itself. Do not test
    only `version_compare( get_bloginfo( 'version' ), '7.1', '>=' )`.
    
    Treat an experimental-plugin version constraint as a deliberate product
    decision. Fail softly when it is absent, and verify the installed source again
    before relying on signatures in a later `0.1.x` release.
    
    ## Use only the seven public PHP functions
    
    The source explicitly marks these as its public contract:
    
    | Function | Contract |
    |---|---|
    | `wp_get_presence( $room, $timeout )` | Return active entry objects for one room. |
    | `wp_set_presence( $room, $client_id, $state, $user_id )` | Atomically upsert one `(room, client_id)` row. |
    | `wp_remove_presence( $room, $client_id )` | Remove one client entry. |
    | `wp_remove_user_presence( $user_id )` | Remove a user's entries across all rooms. |
    | `wp_can_access_presence_room( $room, $user_id )` | Check the plugin's room access policy. |
    | `wp_presence_post_room( $post )` | Return the canonical post room or `false`. |
    | `wp_presence_admin_room()` | Return the canonical `admin/online` room. |
    
    Everything after the public section in `includes/functions.php` is marked
    private even when it has a global `wp_*` function name. Do not depend on
    `wp_get_active_rooms()`, `wp_get_presence_summary()`, table/provisioning
    helpers, or cleanup internals.
    
    The direct PHP write/remove functions are trusted server-side primitives. They
    do not reproduce the REST controller's room-length, payload, ownership, entry
    limit, or capability checks. Validate and authorize before calling them from
    any request handler.
    
    ## Model rooms and authorization together
    
    Core post types `post` and `page` opt in automatically. Add support to a custom
    post type during registration or afterwards:
    
    ```php
    register_post_type(
        'book',
        array(
            'show_ui'  => true,
            'supports' => array( 'title', 'editor', 'presence' ),
        )
    );
    
    $room = wp_presence_post_room( $book_id ); // postType/book:123 or false.
    ```
    
    `postType/{post_type}:{id}` rooms require `edit_post` for that object. Other
    room strings, including `admin/online`, require only `edit_posts`. Therefore a
    custom room name is not a custom authorization boundary. Do not put data in a
    generic room when every user with `edit_posts` must not see it; enforce the
    narrower capability in your own server handler or use an object-backed room.
    
    Presence is awareness, not authorization. Never grant locks, saves, or content
    access merely because a user has a presence entry.
    
    ## Keep state ephemeral and bounded
    
    ```php
    $room      = wp_presence_post_room( $post_id );
    $client_id = 'my-plugin-' . get_current_user_id();
    
    if ( $room && current_user_can( 'edit_post', $post_id ) ) {
        wp_set_presence(
            $room,
            $client_id,
            array( 'mode' => 'reviewing' ),
            get_current_user_id()
        );
    }
    ```
    
    Use stable, namespaced client IDs. Store only small UI state, never secrets,
    tokens, unpublished content bodies, or durable workflow state. Entries expire
    from reads after the TTL and are later removed in bounded cron batches. TTL is
    not a delivery guarantee, logout is not guaranteed to run, and a crashed tab
    can remain visible until expiry.
    
    The table is the correct architectural pattern for high-frequency awareness:
    it avoids repeatedly invalidating `wp_options` or object meta caches. It does
    not make every custom ephemeral feature a reason to depend on this plugin;
    use the public contract only when Presence API's room and capability model fit.
    
    ## Use the REST contract safely
    
    Authenticated endpoints are:
    
    | Method | Route | Purpose |
    |---|---|---|
    | `GET` | `/wp-presence/v1/presence` | Paginated entries for `room`. |
    | `POST` | `/wp-presence/v1/presence` | Upsert `room`, `client_id`, and `data`. |
    | `DELETE` | `/wp-presence/v1/presence` | Delete an owned entry; `manage_options` can delete any. |
    | `GET` | `/wp-presence/v1/presence/rooms` | Paginated, access-filtered active rooms. |
    | `POST` | `/wp-presence/v1/presence/screen-revisions/stale` | Bump an authorized screen revision. |
    
    Use `wp.apiFetch` in WordPress admin/editor JavaScript so the REST nonce and
    root middleware are applied. Respect pagination headers and request `_fields`
    when only user identity is needed. Responses use `Cache-Control: no-store`.
    
    The 0.1.23 controller bounds room/client IDs to 191 characters, REST state to
    10 KiB and three nested array levels, list pages to 100 rows, and active
    entries to 50 per user. It rejects an active `client_id` owned by a different
    user and restricts delete-by-client ownership. Do not clone these values into
    a competing endpoint; use the plugin route or implement an independently
    reviewed contract.
    
    Read `references/api-and-runtime.md` before adding a REST client, custom room,
    screen-revision integration, or multisite dependency.
    
    ## Integrate Heartbeat without multiplying traffic
    
    The plugin enqueues WordPress Heartbeat and writes initial presence on eligible
    admin/front-end requests, then refreshes state through Heartbeat. The block
    editor can run Heartbeat faster than its normal 60-second interval for post
    locks. Do not add a second timer that posts the same state independently.
    
    The shipped `usePresenceUsers()` React hook performs one REST read initially
    and on Heartbeat ticks, deduplicates by user ID, supports `_fields`, and can
    exclude the current user. In 0.1.23 it is shipped as source, not as a registered
    WordPress package or script handle. Do not deep-import another installed
    plugin's filesystem path at runtime. If a build deliberately vendors that
    experimental source, pin the plugin release and review license/update drift;
    otherwise implement a small `wp.apiFetch` consumer around the REST contract.
    
    ## Treat collaboration hooks as advisory in 0.1.23
    
    `wp_presence_editor_state` can enrich editor state. The plugin also declares
    `wp_presence_collaboration_started` and `wp_presence_collaboration_ended`.
    Do not use the latter actions for billing, durable workflow transitions, or
    exact participant lifecycle: in 0.1.23 threshold memory is a request-local
    static variable, so it does not persist a transition state across separate
    Heartbeat requests. Recompute current membership from the room for decisions
    and verify this implementation again after upgrading.
    
    ## Test the whole lifecycle
    
    1. Absence of the feature plugin: integration fails softly.
    2. Supported and unsupported post types: room string versus `false`.
    3. Author can access own editable post but not a post they cannot edit.
    4. Generic custom room visibility for every `edit_posts` user.
    5. REST create/read/delete, ownership conflict, 191-character keys, oversized
       state, nested state, pagination, `_fields`, and `Cache-Control: no-store`.
    6. Two tabs for one user and two users in one room; close/crash/logout/TTL.
    7. Heartbeat active, slowed, suspended, and unavailable.
    8. Table missing during a front-end request: reads return empty and writes
       return `false` instead of causing SQL errors.
    9. Site activation, network activation, new-site creation, large network, cron
       cleanup, deactivation, and uninstall on a real multisite test network.
    10. Dynamic UI with keyboard focus, empty avatar alt text, live-region
        announcements, and reduced motion.
    
    ## Critical rules
    
    - Presence API 0.1.23 is an experimental plugin, not WordPress 7.1 core.
    - Feature-detect it and use only the seven explicitly public PHP functions.
    - Keep capability checks at every write/read boundary; presence grants nothing.
    - Treat generic rooms as visible to all users with `edit_posts`.
    - Keep state small, non-secret, ephemeral, and retry-safe.
    - Reuse Heartbeat; do not add a competing polling loop.
    - Do not depend on private global helpers or exact internal table queries.
    - Do not treat collaboration threshold hooks as durable transition events.
    
    ## Cross-references
    
    - Use **`wp-rest-api`** when implementing a separate custom endpoint.
    - Use **`wp-plugin-options-storage`** for the custom-table decision.
    - Use **`wp-plugin-cron`** for cleanup reliability and multisite scheduling.
    
    ## References
    
    - Read `references/api-and-runtime.md` for exact response fields, limits,
      provisioning, stale-screen, and hook details.
    - Active repository and source: <https://github.com/WordPress/presence-api>
    - v0.1.23 release: <https://github.com/WordPress/presence-api/releases/tag/v0.1.23>
    - Feature-plugin announcement: <https://make.wordpress.org/core/2026/04/27/presence-api-feature-plugin/>
    - Verified source paths at tag `v0.1.23`:
      - `presence-api.php`
      - `includes/functions.php`
      - `includes/class-wp-rest-presence-controller.php`
      - `includes/heartbeat.php`
      - `includes/screen-revisions.php`
      - `includes/cron.php`
      - `src/hooks/use-presence-users.js`
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related