Skip to main content

Setup Wizard REST API

Endpoints used by the setup wizard and migration-related screens. Covers wizard step progression, episode import, migration redirect settings, and Patreon shadow subscriber visibility. All endpoints require manage_options and a valid X-WP-Nonce header unless noted otherwise.


Wizard Progression

POST /benecaster/v1/wizard/steps/{id}/complete

Marks a first-run wizard step as complete. {id} is the step’s id, as listed in benecaster_setup_wizard_steps — for example subscribers or tiers.

Body: optional.

Field Type Description
show_id integer The show being set up. When greater than 0 it is recorded as the wizard’s show.
membership_mode string subscribers step only: paid or public. Any other value is ignored.

Response:

{
  "success": true,
  "step_id": "subscribers"
}

Errors:

Code HTTP Condition
invalid_step 404 {id} is not a step in the wizard, or is done

Step definitions are filterable via benecaster_setup_wizard_steps — add-ons can inject additional steps.


POST /benecaster/v1/wizard/complete

Marks the wizard as complete and fires the benecaster_setup_wizard_completed action with the show and its active bridge.

Body: optional. show_id (integer) names the show; without it, the show recorded by the step endpoint is used.

Response:

{
  "success": true
}

There are no error responses beyond authentication: the call does not check that every step was completed.


POST /benecaster/v1/wizard/reset

Returns the wizard to its first-run state, for development and testing. Clears the completion and dismissal flags, the recorded show, the membership mode, every step’s completion marker, and every record of an add-on step offered after setup, on every show. Then fires benecaster_setup_wizard_reset. Shows, episodes and subscribers are untouched.

Body: none.

Response: { "success": true }

Errors:

Code HTTP Condition
disabled_in_production 403 The site is not a local, development or staging environment and WP_DEBUG is off

Add-on Steps After Setup

An add-on installed after the wizard was finished can ask for its step to be run on a show with benecaster_request_wizard_step(). The setup page that runs those steps settles each one through these two endpoints. Each step is settled once per show: completing or declining it is final.

POST /benecaster/v1/wizard/shows/{show_id}/late-steps/{id}/complete

Completes a requested add-on step for one show. {id} is the step’s id. Completion is recorded for that show only; the site-wide step marker the first-run endpoint writes is not touched. Fires benecaster_wizard_late_step_completed the first time. Repeating the call for a completed step returns 200.

Body: none.

Response:

{
  "success": true,
  "step_id": "my-addon-config",
  "show_id": 45,
  "state": "complete"
}

Errors:

Code HTTP Condition
late_step_not_pending 404 The step was never requested for this show, or it was declined

POST /benecaster/v1/wizard/shows/{show_id}/late-steps/{id}/decline

Declines a requested add-on step for one show, permanently: it is not offered on that show again. Fires benecaster_wizard_late_step_declined the first time; repeating the call for a declined step returns 200. The setup page calls this for a skipped step and, when the podcaster leaves part-way, for the step on screen and every step after it.

Body: none.

Response: as for complete, with "state": "declined".

Errors:

Code HTTP Condition
late_step_not_pending 404 The step was never requested for this show, or it was completed

Episode Import

POST /benecaster/v1/shows/{id}/import

Starts a one-time bulk import of every episode in a source RSS feed. Distinct from the recurring feed sync — this imports everything, not just new items. Typically used during setup to bring existing episodes from a previous podcast host. Episodes arrive as drafts.

Body:

{
  "feed_url": "https://feeds.buzzsprout.com/12345.rss"
}

The import runs in the background. The call returns straight away with the job’s first progress snapshot; poll GET below until status is complete or failed. Episodes an earlier import already brought in from a feed are skipped (matched on the source feed’s GUID), so re-running over the same feed does not duplicate them. An episode you created by hand in Benecaster has no source GUID, so importing your own Benecaster feed would duplicate it.

Response — 200:

{
  "status": "running",
  "imported": 0,
  "total": 0,
  "skipped": 0,
  "errors": 0
}

One import per show at a time, and nothing enforces it. Starting a second import while one is running is not refused: the new job becomes the one GET reports on, and the running job’s progress can no longer be read, although it keeps working. Read GET first and do not start another while status is running.

Errors:

Code HTTP Condition
rest_not_found 404 Show ID does not exist
invalid_feed_url 400 feed_url missing or not a valid URL

A feed that cannot be fetched or read does not fail the request — the job starts, then reports status: "failed" with an error_msg.


GET /benecaster/v1/shows/{id}/import

Returns the progress of the show’s current import job — the same shape POST returns.

Response:

{
  "status": "complete",
  "imported": 16,
  "total": 84,
  "skipped": 68,
  "errors": 0
}

status is idle (no import has been started for this show), running, complete or failed. error_msg is present only when status is failed. skipped counts episodes an earlier import already brought in; errors counts items that could not be created. The job ID is not exposed — this always reports the show’s most recent job.


Migration / Redirect Settings

PUT /benecaster/v1/shows/{id}/migration

Update migration and redirect settings for a show. Used by the setup wizard’s Migration step and the Show Settings → Migration tab.

Body:

{
  "redirect_from_url": "https://feeds.buzzsprout.com/12345.rss",
  "new_feed_url": null,
  "redirect_expires": "2026-08-17"
}
Field Description
redirect_from_url The old feed URL this show is replacing. Stored for reference and shown in setup UI. Not used to generate redirects — feed redirect is handled by a 301 rewrite rule.
new_feed_url If set, Benecaster emits <itunes:new-feed-url> in its own feed pointing here. Use when migrating away from Benecaster.
redirect_expires Date to stop emitting the <itunes:new-feed-url> tag. After this date, the tag is omitted from the feed. Fires benecaster_redirect_expiry_run when the cron removes it.

All fields are optional — only provided fields are updated.

Response: Updated show object with migration fields.

Errors:

Code HTTP Condition
show_not_found 404 Show ID does not exist
invalid_param 400 redirect_expires is not a valid date; new_feed_url or redirect_from_url not a valid URL

Shadow Subscriber Visibility (Patreon Import)

These endpoints manage the “visibility” scorecard — a platform’s patron or subscriber list uploaded for comparison with Benecaster subscribers before a migration decision.

GET /benecaster/v1/shows/{id}/visibility

Returns the current shadow subscriber state for a show — one entry per uploaded platform.

Response:

{
  "items": [
    {
      "platform": "patreon",
      "patron_count": 89,
      "uploaded_at": "2026-04-17T09:00:00",
      "expires_at": "2026-07-16T09:00:00",
      "expired": false
    }
  ]
}
Field Description
platform Platform identifier: patreon, supercast, or a custom slug
patron_count Number of patron records in the uploaded dataset
uploaded_at ISO 8601 datetime of the most recent upload
expires_at ISO 8601 datetime when this data will be automatically removed (90 days from upload)
expired true when past expires_at — data has been purged; re-upload required

Errors:

Code HTTP Condition
show_not_found 404 Show ID does not exist

POST /benecaster/v1/shows/{id}/visibility/csv

Upload a patron export CSV to populate the shadow subscriber scorecard.

Body: multipart/form-data with a file field containing the CSV.

Response:

{
  "platform": "patreon",
  "patrons_imported": 89,
  "patrons_already_subscribed": 12,
  "expires_at": "2026-07-16T09:00:00"
}
Field Description
patrons_imported Total patron records in the uploaded CSV
patrons_already_subscribed Patrons already found as active Benecaster subscribers (deduped on email)
expires_at 90 days from upload — when the data will be automatically removed

The platform (e.g. patreon) is auto-detected from the CSV structure. Re-uploading for the same platform resets the uploaded_at and expires_at clocks and replaces all previous records.

Errors:

Code HTTP Condition
show_not_found 404 Show ID does not exist
invalid_param 400 No file provided
invalid_csv 422 CSV format not recognized

POST /benecaster/v1/shows/{id}/visibility/count

Register a manual patron count without uploading a CSV. For platforms that don’t support CSV export or when only an aggregate number is available.

Body:

{
  "platform": "patreon",
  "count": 47
}

Response:

{
  "platform": "patreon",
  "patron_count": 47,
  "uploaded_at": "2026-05-17T09:00:00",
  "expires_at": "2026-08-15T09:00:00"
}

Manual count entries are not deduplicable (no individual records) and expire at the same 90-day schedule as CSV uploads.


DELETE /benecaster/v1/shows/{id}/visibility/{platform}

Removes all shadow subscriber data for a specific platform from a show. Equivalent to the Clear button on the show’s Visibility tab.

Response: 204 No Content

Errors:

Code HTTP Condition
show_not_found 404 Show ID does not exist
rest_not_found 404 No visibility data for this platform on this show

See Also

Need this built rather than just documented? See our services →