Account REST API (Subscriber-Facing)
These are the endpoints called by the [[benecaster_account]](/shortcodes/benecaster-account/) shortcode on the subscriber-facing account page. They use cookie authentication and verify the current user owns the resource — they do not use X-WP-Nonce or require manage_options. Each endpoint checks that the currently logged-in user is requesting their own data, so responses are always scoped to the caller’s own account.
GET /benecaster/v1/account/subscriptions
Returns all active Benecaster subscriptions for the currently logged-in user — one entry per show the user holds an active token for.
Auth: Cookie (logged-in subscriber). No manage_options required.
Response:
{
"items": [
{
"show_id": 45,
"show_title": "My Podcast",
"show_artwork": "https://example.com/artwork.jpg",
"tier_name": "Premium",
"feed_url": "https://yoursite.com/podcast-feed/?token=abc...",
"status": "active",
"token_prefix": "abc12345"
}
]
}
Response fields:
| Field | Description |
|---|---|
show_id |
Show database ID |
show_title |
Show display name |
show_artwork |
Show artwork URL; null if no artwork set |
tier_name |
Subscriber’s current tier display name |
feed_url |
Subscriber’s full private RSS feed URL |
status |
active (only active tokens returned) |
token_prefix |
First 8 characters of the token — displayed in the account UI for identification; the full token is in feed_url |
Errors:
| Code | HTTP | Condition |
|---|---|---|
rest_forbidden |
401 | User not logged in |
The [benecaster_account] shortcode calls this endpoint on render to populate the subscription list. The response is not cached — each page load reflects the current token state.
Rate limit: 300 requests per 5 minutes per IP (catch-all standard bucket — no bespoke bucket for this endpoint). Shared across all IPs on the same network (household NAT, coworking spaces). Returns 429 Too Many Requests with Retry-After header when exceeded. Operators can tighten this via the benecaster_rest_rate_limit_buckets filter.
POST /benecaster/v1/account/reset-token
Subscriber resets their own feed token for a specific show. Generates a new token and immediately invalidates the old one. The subscriber’s podcast app will receive the new URL on its next feed poll — the app doesn’t need to be manually updated unless the subscriber uses a direct feed subscription (not a token-aware app link).
Auth: Cookie (logged-in subscriber).
Body:
{
"show_id": 45
}
Response:
{
"feed_url": "https://yoursite.com/podcast-feed/?token=xyz...",
"token_prefix": "xyz98765",
"app_links": {
"apple_podcasts": "podcast://yoursite.com/podcast-feed/?token=xyz...",
"overcast": "overcast://x-callback-url/add?url=...",
"pocket_casts": "pktc://subscribe/yoursite.com/...",
"castro": "castro://subscribe/yoursite.com/..."
}
}
Response fields:
| Field | Description |
|---|---|
feed_url |
Complete new feed URL including the full token |
token_prefix |
First 8 characters of the new token |
app_links |
Deep links for major podcast apps, pre-loaded with the new feed URL |
Notes:
- This endpoint returns the full token in
feed_url. The admin endpoint (POST /subscribers/{id}/reset-token) truncates to a prefix — this endpoint does not, because the subscriber needs the complete URL. - Auth check: the endpoint only resets the token for the currently logged-in user — it is not possible to reset another subscriber’s token via this endpoint.
- A
404is returned when the user has no active token for the given show.
Errors:
| Code | HTTP | Condition |
|---|---|---|
invalid_param |
400 | show_id missing or not an integer |
rest_forbidden |
401 | User not logged in |
rest_not_found |
404 | User has no active token for show_id |
Rate limit: 5 requests per hour per user. Returns 429 Too Many Requests with Retry-After header when exceeded.
GET /benecaster/v1/account/qr-code
Returns QR code image data for the subscriber’s feed URL for a specific show.
Auth: Cookie (logged-in subscriber).
Parameters:
| Param | Type | Default | Description |
|---|---|---|---|
show_id |
int | — | Required |
format |
string | svg |
svg or png |
size |
int | 200 | Display size in pixels (does not affect download resolution) |
Response: Binary image data with Content-Type: image/svg+xml or Content-Type: image/png.
For SVG: print-ready at 50 mm × 50 mm regardless of size parameter.
For PNG: 1000 × 1000 pixels regardless of size parameter.
The size parameter controls the width and height attributes on the <img> element when the [benecaster_qr_code] shortcode renders the image in the page — it is a display hint only.
Errors:
| Code | HTTP | Condition |
|---|---|---|
invalid_param |
400 | show_id missing; format not svg or png; size not a positive integer |
rest_forbidden |
401 | User not logged in |
rest_not_found |
404 | User has no active token for show_id |
Rate limit: 30 requests per 5 minutes. Returns 429 Too Many Requests with Retry-After header when exceeded.
POST /benecaster/v1/account/supporter-wall-visibility
Sets whether the currently logged-in subscriber appears on the Supporter Wall for their show(s). Called by the opt-in checkbox in the Profile picture / Badges block of [benecaster_account].
Auth: Cookie (logged-in subscriber).
Body:
{
"visible": true
}
Response:
{
"visible": true
}
Behavior:
- Writes
_benecaster_subscriber_wall_visibleuser meta and returns the value that was written. - Idempotent — submitting
visible: truewhen the subscriber is already opted in still succeeds and still fires thebenecaster_subscriber_wall_visibleaction (always-fires semantics; seebenecaster_subscriber_wall_visible). - Returns
401when the request is not authenticated. - The checkbox on the account page only renders when
benecaster_supporter_wall_activereturnstruefor the subscriber — i.e. at least one of their active shows has the wall enabled. The endpoint itself does not enforce this gate server-side; it accepts requests regardless.
Errors:
| Code | HTTP | Condition |
|---|---|---|
invalid_param |
400 | visible missing or not a boolean |
rest_forbidden |
401 | User not logged in |
Rate limit: 300 requests per 5 minutes per IP (catch-all standard bucket — no bespoke bucket for this endpoint). Operators can tighten this via the benecaster_rest_rate_limit_buckets filter.
Authentication Note
All /account/* endpoints reject requests that are not from a logged-in WordPress user — they return 401 rest_forbidden. This means they cannot be called from server-to-server contexts or external tools without a valid session cookie. If you need to read or modify subscriber data programmatically, use the admin subscriber endpoints (GET /shows/{id}/subscribers, POST /subscribers/{id}/reset-token, etc.) with manage_options + nonce authentication instead.