REST API

Updated

Pro feature. Available in MediaShield Pro.

Base URL: /wp-json/mediashield-pro/v1/

All endpoints require manage_options unless noted. Authentication uses the X-WP-Nonce header with a wp_rest nonce. Two endpoints differ: /bunny/webhook is public (verified by HMAC signature or shared token), and /drm/license only requires a logged-in user.

Platforms#

Method Route Description
GET /platforms List platform connections. Credentials are never returned - the response carries id, platform, extra_config, is_active, connected_by, connected_at
POST /platforms Create a connection. Params: platform (bunny, vimeo, youtube, wistia), api_key, api_secret, extra_config. Bunny requires extra_config.pull_zone_hostname
DELETE /platforms/{id} Remove a connection

Uploads#

Method Route Description
GET /uploads Paginated ms_upload_queue job list. Params: page, per_page, status (pending, uploading, processing, complete, failed)

Uploads themselves are started through free's POST /mediashield/v1/upload/init. Pass driver=bunny|vimeo|youtube|wistia to route an upload to a connected platform; the default is self_hosted.

DRM#

Method Route Permission Description
POST /drm/license logged_in Issue a streaming ClearKey license and return a JWK Set. Params: video_id (required), device_id. Duration comes from ms_drm_license_duration_streaming (default 86400 seconds)
POST /drm/revoke manage_options Revoke all licenses for a user+video pair. Params: video_id, user_id (both required)

There is no offline or persistent-license endpoint. The persistent license type and the PWA offline feature were removed in 1.2.0; WidevineLicense::issue_license() now rejects any type other than streaming, and the ENUM value survives only for historical rows.

/drm/license also returns 404 drm_key_not_found unless a content key exists in ms_drm_keys for the video. Nothing in 1.3.0 generates one automatically - see the DRM notes in the overview.

Platform Browsing and Import#

Method Route Description
GET /bunny/videos List Bunny Stream library videos
POST /bunny/import Import Bunny videos into MediaShield
GET /bunny/collections List Bunny collections
POST /bunny/webhook Receive Bunny encoding callbacks (public; HMAC signature or ms_token query arg required)
GET /youtube/videos List YouTube channel videos
POST /youtube/import Import YouTube videos
GET /youtube/playlists List YouTube playlists
GET /vimeo/videos List Vimeo account videos
POST /vimeo/import Import Vimeo videos
GET /vimeo/folders List Vimeo folders
GET /wistia/videos List Wistia project videos
POST /wistia/import Import Wistia videos
GET /wistia/projects List Wistia projects

Analytics#

Method Route Description
GET /analytics/heatmap/{id} 10-second bucket heatmap data for a video (from ms_heatmap_cache)
GET /analytics/playlist-funnel/{playlist_id} Drop-off analysis for a playlist. No admin screen consumes this - API only
GET /analytics/device-breakdown Device and browser distribution. Param: period (default 30d)
GET /realtime/viewers Active sessions (is_active = 1 and last heartbeat within 5 minutes)
GET /analytics/suspicious Paginated activity alerts. Params: page, per_page (default 20)
PATCH /analytics/suspicious/{id}/dismiss Dismiss an alert (sets is_dismissed = 1)
POST /analytics/suspicious/safe-user Whitelist a user. Param: user_id. Also dismisses that user's open alerts

Milestones#

Method Route Description
GET /milestones/config Retrieve milestone action configuration (ms_pro_milestone_config)
PUT /milestones/config Save the configuration. Body: {config: [{threshold, actions: [{type, config}]}]} or a bare array. threshold 1-100, type one of tag, email, webhook
POST /milestones/test-action Fire one action once against the current admin. Body: {type, threshold, config}

The config has no per-video dimension - a milestone action applies to every video.

Export#

Method Route Description
GET /export/csv/{type} Stream CSV. {type}: watch_sessions, milestones, users. Params: date_from, date_to, user_id, video_id. No cap on watch-session and milestone exports since 1.3.0 - they keyset-page and export in full. The user export keeps a 200,000-row ceiling and writes a NOTE row into the CSV if it is reached. Requires _wpnonce (the download is a plain anchor navigation, so the nonce travels in the query string)
POST /export/pdf/report Queue an async PDF report. Param: period (7d, 30d, 90d, all; default 30d). Returns 202 with { job_id, status, message }
GET /export/status/{job_id} Check PDF job status. Adds download_url once the job is complete

Reports#

Method Route Description
POST /digest/send-test Render the weekly digest and send it to the requesting admin's email, not the configured digest address. Returns sent: false with reason digest_disabled_or_no_recipient when ms_weekly_digest_enabled is off

License#

Method Route Description
GET /license Current license state: key_masked, has_key, status (raw store object), is_valid, has_bypass, item_id, store_url
POST /license Activate a key against the wbcomdesigns.com store
DELETE /license Deactivate the stored key and free the store slot

All Pro routes use the mediashield-pro/v1 namespace exclusively. No Pro routes are registered under mediashield/v1.