Skip to main content

Add-on Activation REST API

Powers the per-show on/off control on every entitled card in Settings → Add-ons.

The distinction this API exists to hold apart is entitlement versus activation. Entitlement is what a licence grants and is decided entirely by the licence server. Activation is the podcaster’s own choice about which of their shows actually runs an add-on they already own. This API writes the second and never the first — it never calls the licence server.

Purchase is licence-wide; activation is per show. A Multi-Show customer who owns an add-on can run it on shows A and B and leave it off on C, with no second purchase.


GET /addons/activation

Returns per-show activation state for the Add-ons screen.

Auth: manage_options plus a valid wp_rest nonce.

Body: none.

Response (200): one row per published show.

{
  "shows": [
    {
      "id": 42,
      "uuid": "8f3c1a90-...",
      "title": "The Example Show",
      "granted": [ "email-editor", "analytics-dashboard" ],
      "disabled": [ "analytics-dashboard" ]
    }
  ]
}
Field Type Description
id int Show post ID
uuid string The show’s _benecaster_show_uuid
title string Show title
granted string[] Slugs this show’s licence entitles
disabled string[] Slugs the podcaster has switched off for this show

Read disabled, not an enabled list. Only switch-offs are stored, so absence means on. That is why a newly granted add-on is active the moment the grant arrives, with no migration and no backfill.

Shows whose licence does not grant an add-on are still listed, with the add-on simply absent from granted. The screen renders them with the reason — “Not on this show’s licence” — rather than hiding them. A missing control on one show of three reads as a bug rather than a licence boundary, and that is the failure this control exists to prevent.


POST /addons/activation

Switches one add-on on or off for one show.

Auth: manage_options plus a valid wp_rest nonce.

Body

Name Type Description
show_id int The show to change
addon_slug string The add-on to switch
enabled bool true to switch on, false to switch off

Response (200): the rebuilt row set, in the same shape as GET.

The write returns the full refreshed state rather than an acknowledgement, so the screen renders confirmed server state instead of its own optimistic guess. A client that patches its local copy on a bare 200 will eventually disagree with the server, and the disagreement shows up only after a save.

Errors (400)

Code Meaning
invalid_show_id show_id missing, non-positive, or not a benecaster_show post
missing_addon_slug addon_slug empty after sanitisation
no_show_uuid the show has no _benecaster_show_uuid
addon_not_granted this show’s licence does not grant the slug

addon_not_granted is a refusal, not a validation nicety. A stored “off” for an add-on that was never granted is indistinguishable from a deliberate choice on the day the licence does grant it — the customer would buy the add-on and find it already switched off on that one show, with nobody having switched it off.


What a successful write fires

do_action( 'benecaster_addon_activation_changed', string $addon_slug, int $show_id, bool $enabled );

This is an activation change, never an entitlement change. The customer still owns the add-on and is expected to switch it back on. A listener may drop per-show caches, transients and scheduled tasks — but must not destroy anything the customer authored or paid for, because the next switch-on cannot undo a delete.

See benecaster_addon_activation_changed.


Reading activation state in code is benecaster_addon_is_active(), which takes a required show context. Its install-wide companion, benecaster_addon_is_active_for_any_show(), answers a different question and must not be substituted for it.

See Also