Contents
On this page

Get Video Source - Plugixa Video

GET /pvx/v1/videos/{id}/source

Get the playable URL or embed of a video, after the access check. This is the only route that ever returns a video’s source.

Public, then decided per video: a free video plays for anyone, a members video for any signed-in user, a paid video PRO for a buyer or member. Whoever may edit the video may always play it, drafts included.

Note. Every successful call counts as a view (views on the video), with no de-duplication. Do not call it to check access, or to warm a cache.

Note. The answer carries Cache-Control: no-store, private. With Pro, an uploaded video plays through a signed link that expires (5 minutes by default, plus the video’s length for a converted video), so do not store url.

Request

GET https://your-site.example/wp-json/pvx/v1/videos/838/source

Path parameters

Name Type Description
id integer The video’s id

Responses

200 OK, an HLS or MP4 video. progress is there for a signed-in caller.

{
  "success": true,
  "data": {
    "id": 838,
    "type": "mp4",
    "title": "Iceland: The Ring Road",
    "poster": "https://your-site.example/wp-content/uploads/2026/11/ring-road-1024x576.jpg",
    "duration": 1460,
    "url": "https://cdn.your-site.example/videos/ring-road.mp4",
    "chapters": [
      {
        "start": 0,
        "title": "Reykjavik"
      },
      {
        "start": 250,
        "title": "The Golden Circle"
      },
      {
        "start": 750,
        "title": "Jokulsarlon"
      }
    ],
    "progress": {
      "position": 412,
      "duration": 1460,
      "completed": false
    }
  }
}
Field Type Meaning
data.type string hls or mp4 here
data.url string The URL to play
data.chapters object[] {start, title} read from the description, start in seconds. Empty unless there are at least two
data.captions object[] {lang, label, url, default} subtitle tracks PRO
data.progress object|null The caller’s saved position, null if none. Absent when signed out

200 OK, a YouTube or Vimeo video.

{
  "success": true,
  "data": {
    "id": 840,
    "type": "youtube",
    "title": "Faroe Islands by Ferry",
    "poster": "https://your-site.example/wp-content/uploads/2026/11/ring-road-1024x576.jpg",
    "duration": 920,
    "embed": "https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ?rel=0&modestbranding=1&playsinline=1"
  }
}
Field Type Meaning
data.embed string An embed URL: youtube-nocookie.com for YouTube, player.vimeo.com with dnt=1 for Vimeo

A signed-in caller also gets progress here.

401 Locked, and the caller is signed out.

{
  "code": "plugixa_video_login_required",
  "message": "Sign in to watch this video.",
  "data": {
    "teaser": {
      "id": 851,
      "title": "Patagonia: The Long Way South",
      "poster": "https://your-site.example/wp-content/uploads/2026/11/ring-road-1024x576.jpg",
      "access": "members",
      "price": 0.0
    },
    "unlock": {
      "offers": [],
      "action": "",
      "methods": []
    },
    "status": 401
  }
}
Field Type Meaning
data.teaser object What a lock screen can show: id, title, poster, access, price
data.unlock.offers object[] Ways to unlock it. Always empty in the free plugin; Pro’s Payments app fills it
data.unlock.action string The route a checkout is posted to, or empty

A signed-in caller without access gets the same body with 403 and plugixa_video_locked.

Errors

Status Code When
404 plugixa_video_not_found No video with that id, or one that is not published or unlisted (a draft, scheduled, pending or private video) and the caller may not edit.
403 plugixa_video_password_required The video has a password PRO and the caller may not edit it. Checked first, and without a teaser.
401 plugixa_video_login_required Signed out, and the video is not free.
403 plugixa_video_locked Signed in, but the video is not part of the caller’s access.
422 plugixa_video_unplayable The video has no URL, or a YouTube or Vimeo URL no id could be read from.

Plus the errors every endpoint can return.

Examples

curl -s "https://your-site.example/wp-json/pvx/v1/videos/838/source"
<?php
$ch = curl_init('https://your-site.example/wp-json/pvx/v1/videos/838/source');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const response = await fetch('https://your-site.example/wp-json/pvx/v1/videos/838/source');
const { data } = await response.json();

Quick Links

Share