API Reference

Here's everything you need to know to integrate and use Pixop's REST API.

Light orange banner with white and orange icons

Pixop Video Processing REST API v1

The API is split across 3 services: accounts, videos and media.

  1. The Accounts Service Endpoints allow you to authenticate your account credentials, generate an auth (JWT) token for use in other API calls, and perform some basic account management operations on your account. A JWT token is valid for 15 minutes.
  2. The Videos Service Endpoints allow you to create and browse and manage projects and their associated videos, as well as triggering requests to apply processing to videos that have been uploaded and tracking the progress of any in progress processing requests.
  3. The Media Service Endpoints allow you to upload video files that relate to a video item, and to download the resultant processed media.

Services List


Accounts Service Endpoints

Root path: https://staging-api.pixop.com/accounts

Required Header Value
Authorization Bearer [JWT-TOKEN] or HTTP Basic authentication (email/password)
Accept application/json
Content-Type application/json

Authenticate account credentials and generate JWT token

  • Subpath: /v1/token
  • Method: GET
  • Authentication: HTTP Basic auth in Authorization header (passing email and password)
Request Parameter Mandatory Purpose
team-id No Optionally select a team that this user belongs to which will apply to all subsequent requests that use this generated auth token

Response:

{
  "userId": ".... user id ....",
  "teamId": ".... team id ....",
  "jwtToken": ".... token ...."
}

Authenticate JWT token and return associated account and team identity

  • Subpath: /v1/token
  • Method: POST
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Response (Success):

{
  "user": {
    "id": ".... user id ....",
    "name": " .... name ....",
    "email": ".... email address ....",
    "emailConfirmed": [boolean, true if email has been confirmed],
    "authSignatureMethod": ".... JWT signature algorithm ....",
    "authSignaturePublicKey": ".... public key used for signing JWT ....",
    "authSignaturePublicKeyId": ".... public key id used for signing JWT ....",
    "banned": [boolean, true if user has been banned],
    "bannedReason": ".... reason ....",
    "bannedDate": "YYYY-MM-DD hh:mm:ss",
    "apiRequestSignatureSecret": ".... shared secret used for signing API requests ....",
    "apiRequestSignatureSethod": ".... signing algorithm for signing API requests ....",
    "dateCreated": "YYYY-MM-DD hh:mm:ss",
    "timeLastUpdated": "YYYY-MM-DD hh:mm:ss"
  },
  "team": {
    "id": ".... team id ....",
    "name": ".... team name ....",
    "restricted": [boolean, true if team is restricted],
    "dateCreated": "YYYY-MM-DD hh:mm:ss",
    "timeLastUpdated": "YYYY-MM-DD hh:mm:ss"
  },
  "otherTeams": [
    {
      "id": ".... team id ....",
      "name": ".... team name ....",
      "restricted": [boolean, true if team is restricted],
      "dateCreated": "YYYY-MM-DD hh:mm:ss",
      "timeLastUpdated": "YYYY-MM-DD hh:mm:ss"
    },
    {
      "id": ".... team id ....",
      "name": ".... team name ....",
      "restricted": [boolean, true if team is restricted],
      "dateCreated": "YYYY-MM-DD hh:mm:ss",
      "timeLastUpdated": "YYYY-MM-DD hh:mm:ss"
    },
    .....
  ]
}

Response (Failure):

{
  "exception": ".... exception ....",
  "errorMessage": ".... error message ...."
}
Exception Meaning
InvalidJWTTokenFoundException The JWT Token supplied could not be interpreted for some reason (e.g. corrupt)
NoJWTTokenFoundException No JWT Token was supplied in the Authorization header for this request
ExpiredJWTTokenException The JWT Token supplied is no longer valid, the expiration time has passed
PrematureJWTTokenException The JWT Token supplied is not valid yet, i.e. it is not yet the ‘not before’ time in the token
UserBannedException The User account referenced by this JWT Token has been suspended and may not use the API
EternalJWTTokenException The JWT Token does not have a TTL which is a security vulnerability. Such tokens are not permitted by this API
InconsistentJWTClaimsException The claims inside this JWT token are not suitable for use by this API
AuthException There was a general service failure whilst trying to authenticate this JWT token

Retrieve account details

  • Subpath: /v1/account
  • Method: GET
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Response:

{
  "user": {
    "id": ".... user id ....",
    "name": " .... name ...",
    "email": ".... email address ....",
    "emailConfirmed": [boolean, true if email has been confirmed],
    "authSignatureMethod": ".... JWT signature algorithm ....",
    "authSignaturePublicKey": ".... public key used for signing JWT ....",
    "authSignaturePublicKeyId": ".... public key id used for signing JWT ....",
    "banned": [boolean, true if user has been banned],
    "bannedReason": ".... reason why this account is banned ....",
    "bannedDate": "YYYY-MM-DD hh:mm:ss",
    "apiRequestSignatureSecret": ".... shared secret used for signing API requests ....",
    "apiRequestSignatureMethod": ".... signing algorithm for signing API requests ....",
    "dateCreated": "YYYY-MM-DD hh:mm:ss",
    "timeLastUpdated": "YYYY-MM-DD hh:mm:ss"
  },
  "team": {
    "id": ".... team id ....",
    "name": ".... team name ....",
    "restricted": [boolean, true if team is restricted],
    "dateCreated": "YYYY-MM-DD hh:mm:ss",
    "timeLastUpdated": "YYYY-MM-DD hh:mm:ss"
  }
}

Generate authentication secret

  • Subpath: /v1/generate-auth-secret
  • Method: GET
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN] or HTTP Basic auth in Authorization header (passing email and password)

Response:

{
  "user": {
    "id": ".... user id ....",
    "authSignatureMethod": ".... JWT signature algorithm ....",
    "authSignaturePublicKey": ".... public key used for signing JWT ....",
    "authSignaturePublicKeyId": ".... public key id used for signing JWT ....",
    .....
  }
}

Generate API signed-request signature secret

  • Subpath: /v1/generate-signature-secret
  • Method: GET
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN] or HTTP Basic auth in Authorization header (passing email and password)

Response:

{
  "user": {
    "id": ".... user id ....",
    .....
    "apiRequestSignatureSecret": ".... shared secret used for signing API requests ....",
    "apiRequestSignatureMethod": ".... signing algorithm for signing API requests ...."
    .....
  }
}

Update account password

  • Subpath: /v1/update-password
  • Method: POST
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN] or HTTP Basic auth in Authorization header (passing email and password)

Request Body:

{
  "newPassword": ".... new password ...."
}

Response:

{
  "user": {
    "id": ".... user id ....",
    .....
   }
}

Videos Service Endpoints

Root path: https://staging-api.pixop.com/videos

Required Header Value
Authorization Bearer [JWT-TOKEN]
Accept application/json
Content-Type application/json

Retrieve project details

  • Subpath: /v1/project/[project-id]
  • Method: GET
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Response:

{
  "project": {
    "id": ".... project id ....",
    "name": ".... project name ....",
    "teamId": ".... id of team that owns this project ....",
    "dateCreated": "YYYY-MM-DD hh:mm:ss",
    "timeLastUpdated": "YYYY-MM-DD hh:mm:ss"
  }
}

Retrieve paginated list of projects associated with this user

  • Subpath: /v1/projects
  • Method: GET
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]
Request Parameter Mandatory Purpose
page No Navigate to a given page within the paginated results
page-size No How many results to return per page

Response:

{
  "pageSize": ".... page size ....",
  "page": .... page number ....",
  "_links": {
    "self": { "href": ".... API endpoint to this page ...." },
    "next": { "href": ".... API endpoint to next page ...." },
    "previous": { "href": ".... API endpoint to previous page ...." },
    "first": { "href": ".... API endpoint to the first page ...." },
    "last": { "href": ".... API endpoint to the last page ...." }
  },
  "_embedded": {
    "projects": [
      {
        "_links": {
          "self": { "href": ".... API endpoint to call to access project ...." }
        },
        "id": ".... project id ....",
        "name": ".... project name ....",
        "dateCreated": "YYYY-MM-DD hh:mm:ss",
        "timeLastUpdated": "YYYY-MM-DD hh:mm:ss"
      },
      .....
    ]
  }
}

Create new project

  • Subpath: /v1/project
  • Method: PUT
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Request Body:

{
  "name": "... name ...."
}

Response:

{
  "project": {
    "id": ".... project id ....",
    .....
  }
}

Update project details

  • Subpath: /v1/project/[project-id]
  • Method: POST
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Request Body:

{
  "name": "... updated name ...."
}

Response:

{
  "project": {
    "id": ".... project id ....",
    .....
  }
}

Delete project

  • Subpath: /v1/project/[project-id]
  • Method: DELETE
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Note: This request will fail if there are videos currently associated with the project, they must be deleted first.


Retrieve video item details

  • Subpath: /v1/video/[video-id]
  • Method: GET
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Response:

{
  "video" : {
    "id" : ".... video id ....",
    "name" : ".... video name ....",
    "description" : ".... video description ....",
    "projectId" : ".... project id that this video is associated with ....",
    "userId" : ".... user id that uploaded or processed this video ....",
    "teamId" : ".... team id that this video belongs to ....",
    "upload" : {
      "uploadState" : {
        "updatedAt" : "YYYY-MM-DD hh:mm:ss",
        "uploadStatus" : ".... upload status ...."
      },
      "hasFinishedUploading" : [boolean, true if video has finished uploading],
      "fileName" : ".... filename of media file ....",
      "fileSize" : ".... size in bytes of media file ....",
      "fileType" : ".... MIME type of media file  ....",
      "fileContainerName" : ".... description of container format of media file ...."
    },
    "ingestion" : {
      "ingestionState" : {
        "updatedAt" : "YYYY-MM-DD hh:mm:ss",
        "ingestionStatus" : ".... ingestion status ....",
        "videoMetadataAvailable" : [boolean, true if metadata is available]
      },
      "metadata" : {
        "containerName" : ".... short video container name ....",
        "longContainerName" : ".... long video container name ....",
        "codecName" : ".... short codec name ....",
        "longCodecName" : ".... long codec name ....",
        "pixelFormat" : {
          "name" : ".... FFmpeg pixel format name (e.g. 'yuv420p') ....",
          "chromaSubsampling" : {
            "yuv" : ".... YUV chroma subsampling triplet string separated by colons (e.g. '4:2:0') ....",
            "bits" : [integer, number of bits per pixel]
          }
        },
        "frameWidth" : [integer, frame width],
        "frameHeight" : [integer, frame height],
        "averageFramerate" : [float, average number of frames per second],
        "durationInMillis" : [integer, video duration in milliseconds],
        "totalFrames" : [integer, total number of video frames],
        "size" : [integer, file size],
        "videoStreamSize" : [integer, size of video stream]
      },
      "qualityAssessment" : {
        "metrics": [
          {
            "name": ".... metric name ....",
            "sampleMean": [float, measurement computed as mean of all sampled frames],
            "subjectiveLabel": ".... human subjective score label (e.g. 'excellent') ....",
            "subjectiveScore": [float, human subjective score (0-5)]
          },
          .....
        ],
        "overallSubjectiveScore": [float, mean subjective score of all metrics (0-5)]
      }
    },
    "processing": {
      "processingState": {
        "updatedAt": "YYYY-MM-DD hh:mm:ss",
        "processingStatus": ".... processing status ...."
      },
      "processingParameters": {
        "sourceVideo": {
          "startPositionMilliseconds": [integer, start time of clip in milliseconds (optional)],
          "endPositionMilliseconds": [integer, end time of clip in milliseconds (optional)]
        },
        "targetVideo": {
          "preset": {
            "name": .... preset name used to process video ...."
          },
          "container": {
            "name": ".... target container ....",
            "properties": [object, container configuration properties]
          },
          "codec": {
            "name": ".... target codec ....",
            "properties": [object, codec configuration properties]
          },
          "pixelFormat": {
            "name" : ".... target FFmpeg pixel format name (e.g. 'yuv420p') ....",
            "chromaSubsampling" : {
              "yuv" : ".... target YUV chroma subsampling triplet string separated by colons (e.g. '4:2:0') ....",
              "bits" : [integer, number of bits per pixel]
            }
          },
          "bitrate": [integer, target bitrate],
          "frameWidth": [integer, target frame width],
          "frameHeight": [integer, target frame height],
          "videoFilters": [
            {
              "name": ".... video filter id ....",
              "properties": [object, filter configuration properties]
            },
            .....
          ]
        }
      }
    },
    "attributes" : [object, video metadata],
    "dateCreated" : "YYYY-MM-DD hh:mm:ss",
    "timeLastUpdated" : "YYYY-MM-DD hh:mm:ss"
  }
}

Retrieve paginated list of videos associated with this user

  • Subpath: /v1/videos
  • Method: GET
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]
Parameter Mandatory Purpose
project-id No Filter results to only videos associated with this project
parent-id No Filter results to only videos associated with this parent original video
page No Navigate to a given page within the paginated results
page-size No How many results to return per page

Response:

{
  "pageSize": ".... page size ....",
  "page": ".... page number ....",
  "_links": {
    "self": { "href": ".... API endpoint to this page ...." },
    "next": { "href": ".... API endpoint to next page ...." },
    "previous": { "href": ".... API endpoint to previous page ...." },
    "first": { "href": ".... API endpoint to the first page ...." },
    "last": { "href": ".... API endpoint to the last page ...." }
  },
  "_embedded": {
    "videos": [
      {
        "_links": {
          "self": { "href": ".... API endpoint to call to access video ...." }
        },
        "id": ".... video id ....",
        "parentId": ".... parent video id (of processed video) ....",
        "projectId": ".... project id this video belongs to ....",
        "name": ".... name ....",
        "filename": ".... filename ....",
        "dateCreated": "YYYY-MM-DD hh:mm:ss",
        "timeLastUpdated": "YYYY-MM-DD hh:mm:ss"
      },
      .....
    ]
  }
}

Create new video

  • Subpath: /v1/video
  • Method: PUT
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Request Body:

{
  "name": ".... name of video.... (optional)",
  "projectId": "... id of project to associate the video with .... (optional)"
}

Response:

{
  "projectId": ".... project id that this new video was associated with ....",
  "videoId": ".... id of the newly created video item .....",
  "uploadMediaUrl": ".... API endpoint to call to upload media to this video item ...",
  "uploadLightMediaUrl": ".... API endpoint to call to upload light ingested media to this video item ...",
  "processVideoUrl": ".... API endpoint to call to initiate a process video request on this video ..."
}

Trigger a request to process a video

  • Subpath: /v1/process-video/[video-id]
  • Method: POST
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Request Body:

{
  "mediaContainerCodec": {
    "container": "mov",
    "codec": "h264"
  },
  "appleProresProfile": "standard",
  "dnxhdHrProfile": "dnxhd_sq",
  "chromaSubsampling": {
    "yuv": "4:2:2",
    "bits": 8
  },
  "bitrate": {
    "mbps": 20.5
  },
  "deinterlacer": "deint",
  "denoiser": "denoise",
  "stabilizer": "dejit",
  "scaler": "pabsr1",
  "resolution": {
    "tag": "hd_1080p",
    "width": 1920,
    "height": 1080
  },
  "clarityBoost": "low",
  "range": {
    "startPositionMilliseconds": 0,
    "endPositionMilliseconds": 30000
  }
}
Field Mandatory Permitted Value Comments
container No mov QuickTime
mxf Material Exchange Format
mp4 MPEG-4
mts MPEG-2 Transport Stream
codec No h264 H.264 / AVC
prores Apple ProRes
dnxhd Avid DNxHD/HR
xdcam Sony XDCAM HD422
hevc H.265 / HEVC
mpeg2 H.262 / MPEG-2
appleProresProfile Only if codec is prores proxy Apple ProRes “proxy” profile
lt Apple ProRes “LT” profile
standard Apple ProRes “standard” profile
hq Apple ProRes “high quality” profile
4444 Apple ProRes “4444 high quality” profile (without alpha channel processing)
4444xq Apple ProRes “4444 XQ” profile (without alpha channel processing)
dnxhdHrProfile Only if codec is dnxhd dnxhd_lb DNxHD “low bandwidth” profile
dnxhd_sq DNxHD “standard quality” profile
dnxhd_hq DNxHD “high quality” profile
dnxhd_hqx DNxHD “high quality extended 10-bit” profile
dnxhd_444 DNxHD “4:4:4 10-bit” profile
dnxhr_lb DNxHR “low bandwidth” profile
dnxhr_sq DNxHR “standard quality” profile
dnxhr_hq DNxHR “high quality” profile
dnxhr_hqx DNxHR “high quality extended 12-bit” profile
dnxhr_444 DNxHR “4:4:4 12-bit” profile
yuv No 4:1:0 YUV chroma subsampling
4:1:1
4:2:0
4:2:2
4:4:0
4:4:4
bits No 8 Pixel bit depth
10
12
14
16
mbps No [0.01-4000.0] Bitrate (megabits per second)
deinterlacer No deint Pixop Deinterlacer
yadif YADIF (“Yet Another DeInterlacing Filter”)
bwdif Bob Weaver
weston3f Weston Three Field
denoiser No denoise Pixop Denoiser
hqdn3d High Quality DeNoise 3D
stabilizer No dejit Pixop Dejitterer
scaler No pabsr1 Pixop Super Resolution
dvres Pixop Deep Restoration
scale Bicubic Interpolation
tag No hd_1080p This field specifies preset resolution settings instead of specifying explicit width and height
uhd_4k
uhd_8k
width No [16-7680] Width and height must be specified if, and only if there is no tag
height No [16-4320]
clarityBoost No none Defines the amount of contrast enhancement performed when Pixop Super Resolution scaler is selected
marginal
very_low
low
medium
high
very_high
startPositionMilliseconds No [0-duration of video in milliseconds] Used to process a clip
endPositionMilliseconds No [0-duration of video in milliseconds] Used to process a clip

Response:

{
  "sourceVideoId": ".... id of video used as the source for the processing request ....",
  "processedVideoId": ".... video id the processing request will generate ....",
  "projectId": ".... id of project this video is associated with ....",
  "checkProgressUrl": ".... API endpoint to query the progress of the process video operation ....",
  "downloadMediaUrl": ".... API endpoint to download the media from the newly processed video ...."
}

Note: Any of container, codec, chroma subsampling and bitrate will be assumed based on source video metadata and target resolution when not specified in request.


Check progress of a video currently being processed

  • Subpath: /v1/check-process-video-progress/[video-id]
  • Method: GET
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Response:

{
  "videoId": ".... video id ....",
  "projectId": ".... project id ....",
  "processingState": {
    "updatedAt": "YYYY-MM-DD hh:mm:ss",
    "processingStatus": ".... processing status ....",
    "processingProgressPercent": [float, percentage processed]
  }
}

Check progress of a video currently being ingested

  • Subpath: /v1/check-ingest-video-progress/[video-id]
  • Method: GET
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Response:

{
  "videoId": ".... video id ....",
  "projectId": ".... project id ....",
  "ingestionState": {
    "updatedAt": "YYYY-MM-DD hh:mm:ss",
    "ingestionStatus": ".... ingestion status ....",
    "videoMetadataAvailable": [boolean, true if metadata is available]
  }
}

Delete video and any new media generated so far

  • Subpath: /v1/video/[video-id]
  • Method: DELETE
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Response:

{
  "deletedVideos": [
    {
      "videoId": ".... deleted video id 1 ...."
    },
    {
      "videoId": ".... deleted video id 2 ...."
    },
    .....
  ]
}

Note: All processed videos are also deleted when an original video is specified.


Media Service Endpoints

Root path: https://staging-api.pixop.com/media

Required Header Value
Authorization Bearer [JWT-TOKEN]

Upload media relating to a video item

  • Subpath: /v1/upload/[video-id]
  • Method: POST
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]
  • Required Header: Content-Type: multipart/form-data

Request Body: A MIME multipart form file upload request containing the raw binary of the media payload, specifying the filename and content-type in the MIME envelope

Response:

{
  "projectId": ".... project id that this new video was associated with ....",
  "videoId": ".... id of the newly created video item .....",
  "checkIngestProgressUrl": ".... API endpoint to query the progress of the ingest video operation ....",
  "processVideoUrl": ".... API endpoint to call to initiate a process video request on this video ...."
}

Upload media relating to a video item for light ingestion

  • Subpath: /v1/upload/light/[video-id]
  • Method: POST
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]
  • Required Header: Content-Type: multipart/form-data

Notes:

  1. Only metadata is ingested. Thumbnails and web video artifacts are not generated, and quality assessment is not performed. Useful for third party integrations that process video in an ephemeral way.
  2. Refer to the Upload media relating to a video item endpoint documentation as this endpoint is functionally similar.

Download original media associated with a video item

  • Subpath: /v1/download/original/[video-id]
  • Method: GET / HEAD
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Request:

Request Header Required Purpose
Authorization Yes Bearer [JWT-TOKEN]
If-None-Match No Cache-control, if the etag of the stored media matches (ie, no update since the last download, then respond with a 304 Not Modified
Range No Allow the download to be resumed, or downloaded in sections

Response:

Response Header Purpose
Content-Disposition Filename of the downloaded media
Etag Hash of the currently stored media, can be passed in If-None-Match header of a future download request for cache-control purposes
Content-Range If a Range header was supplied
Content-Length Size of the stored media file
HTTP Method Response body contents
GET The raw video file originally uploaded in binary form
HEAD Empty response body

Download processed media associated with a video item

  • Subpath: /v1/download/processed/[video-id]
  • Method: GET / HEAD
  • Authentication: A valid JWT token passed in Authorization header :: Authorization Bearer [TOKEN]

Access the raw processed video file that has been generated by the video processing operation.

Note: Refer to the Download original media associated with a video item endpoint documentation as this endpoint is functionally similar.


Latest updated: November 13, 2020

Stay in the loop

Sign up to receive the latest news, offers and alerts.