Plex Timeline API

The actions feature within a media provider

Operations 3

PUT /:/scrobble Mark an item as played #
POST /:/timeline Report media timeline #
PUT /:/unscrobble Mark an item as unplayed #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/plex-timeline-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

plex-timeline-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Plex Media Server Timeline API
  version: '1.2.2

    '
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
  description: '# API Info

    ## Content Types

    The API supports responses in both XML and JSON, and clients can request one or the other using the standard `Accept` HTTP header.'
servers:
- url: https://{IP-description}.{identifier}.plex.direct:{port}
  variables:
    IP-description:
      default: 1-2-3-4
      description: A `-` separated string of the IPv4 or IPv6 address components
    identifier:
      default: 0123456789abcdef0123456789abcdef
      description: The unique identifier of this particular PMS
    port:
      default: '32400'
security:
- user_token:
  - shared user
  - admin
tags:
- name: Timeline
  description: The actions feature within a media provider
paths:
  /:/scrobble:
    put:
      tags:
      - Timeline
      operationId: putScrobble
      summary: Mark an item as played
      description: 'Mark an item as played. Note, this does not create any view history of this item but rather just sets the state as played. The client must provide either the `key` or `uri` query parameter

        This API does respond to the GET verb but applications should use PUT'
      parameters:
      - in: query
        name: identifier
        required: true
        schema:
          type: string
        description: The identifier of the media provider containing the media to rate.  Typically `com.plexapp.plugins.library`
      - in: query
        name: key
        required: false
        schema:
          type: string
        description: The key of the item to rate.  This is the `ratingKey` found in metadata items
      - in: query
        name: uri
        required: false
        schema:
          type: string
        description: The URI of the item to mark as played.  See intro for description of the URIs
      responses:
        '200':
          $ref: '#/components/responses/200'
        '400':
          description: Bad Request.  Can occur when parameters are of the wrong type, or missing
          content:
            text/html:
              examples:
                badRequest:
                  summary: A parameter has a bad value or required parameter is missing
                  value: <html><head><title>Bad Request</title></head><body><h1>400 Bad Request</h1></body></html>
        '404':
          description: Indicates that no library with the provide identifier can be found or no item can be found with the rating key
          content:
            text/html:
              examples:
                notFound:
                  summary: Not Found
                  value: <html><head><title>Not Found</title></head><body><h1>404 Not Found</h1></body></html>
  /:/timeline:
    post:
      tags:
      - Timeline
      summary: Report media timeline
      description: This endpoint is hit during media playback for an item. It must be hit whenever the play state changes, or in the absence of a play state change, in a regular fashion (generally this means every 10 seconds on a LAN/WAN, and every 20 seconds over cellular).
      operationId: timelinePostSlash
      parameters:
      - in: query
        name: key
        schema:
          type: string
        example: /foo
        description: The details key for the item.
      - in: query
        name: ratingKey
        schema:
          type: string
        example: xyz
        description: The rating key attribute for the item.
      - in: query
        name: state
        schema:
          type: string
          enum:
          - stopped
          - buffering
          - playing
          - paused
        example: playing
        description: The current state of the media.
      - in: query
        name: playQueueItemID
        schema:
          type: string
        example: 123
        description: If playing media from a play queue, the play queue's ID.
      - in: query
        name: time
        schema:
          type: integer
        example: 0
        description: The current time offset of playback in ms.
      - in: query
        name: duration
        schema:
          type: integer
        example: 10000
        description: The total duration of the item in ms.
      - in: query
        name: continuing
        schema:
          type: integer
          enum:
          - 0
          - 1
        example: 1
        description: When state is `stopped`, a flag indicating whether or not the client is going to continue playing anothe item.
      - in: query
        name: updated
        schema:
          type: integer
        example: 14200000
        description: Used when a sync client comes online and is syncing media timelines, holds the time at which the playback state was last updated.
      - in: query
        name: offline
        schema:
          type: integer
          enum:
          - 0
          - 1
        example: 1
        description: Also used by sync clients, used to indicate that a timeline is being synced from being offline, as opposed to being "live".
      - in: query
        name: timeToFirstFrame
        schema:
          type: integer
        example: 1000
        description: Time in seconds till first frame is displayed.  Sent only on the first playing timeline request.
      - in: query
        name: timeStalled
        schema:
          type: integer
        example: 1000
        description: Time in seconds spent buffering since last request.
      - in: query
        name: bandwidth
        schema:
          type: integer
        example: 100
        description: Bandwidth in kbps as estimated by the client.
      - in: query
        name: bufferedTime
        schema:
          type: integer
        example: 100
        description: Amount of time in seconds buffered by client.  Omit if computed by `bufferedSize` below.
      - in: query
        name: bufferedSize
        schema:
          type: integer
        example: 1024
        description: Size in kilobytes of data buffered by client.  Omit if computed by `bufferedTime` above
      - in: header
        name: X-Plex-Client-Identifier
        schema:
          type: string
        required: true
        description: Unique per client.
      - in: header
        name: X-Plex-Session-Identifier
        schema:
          type: string
        description: Unique per client playback session.  Used if a client can playback multiple items at a time (such as a browser with multiple tabs)
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  MediaContainer:
                    allOf:
                    - $ref: '#/components/schemas/serverConfiguration'
                    - type: object
                      properties:
                        terminationCode:
                          type: integer
                          description: A code describing why the session was terminated by the server.
                        terminationText:
                          type: string
                          description: A user friendly and localized text describing why the session was terminated by the server.
                        Bandwidths:
                          type: object
                          description: A list of media times and bandwidths when trascoding is using with auto adjustment of bandwidth
                          properties:
                            Bandwidth:
                              type: array
                              items:
                                type: object
                                properties:
                                  time:
                                    type: integer
                                    description: Media playback time where this bandwidth started
                                  bandwidth:
                                    type: integer
                                    description: The bandwidth at this time in kbps
                                  resolution:
                                    type: string
                                    description: The user-friendly resolution at this time
              examples:
                normal:
                  description: Normal response
                  value:
                    MediaContainer:
                      size: 0
                adminTerminatedSession:
                  description: Admin Terminated the session
                  value:
                    MediaContainer:
                      size: 0
                      terminationCode: 2006
                      terminationText: 'Admin terminated playback with reason: Go Away'
                bandwidthChanges:
                  description: Bandwidth changes included
                  value:
                    MediaContainer:
                      size: 1
                      Bandwidths:
                        Bandwidth:
                        - time: 0
                          bandwidth: 15000
                          resolution: 1080p
                        - time: 1050008
                          bandwidth: 12000
                          resolution: 1080p
                        - time: 1053011
                          bandwidth: 8000
                          resolution: 1080p
                        - time: 1098014
                          bandwidth: 4000
                          resolution: 720p
                        - time: 1101017
                          bandwidth: 2000
                          resolution: SD
                        - time: 1104020
                          bandwidth: 1000
                          resolution: SD
                        - time: 1107023
                          bandwidth: 750
                          resolution: SD
                        - time: 1110026
                          bandwidth: 350
                          resolution: SD
                        - time: 1113029
                          bandwidth: 750
                          resolution: SD
                        - time: 1116032
                          bandwidth: 1000
                          resolution: SD
                        - time: 1119035
                          bandwidth: 4000
                          resolution: 720p
                        - time: 1122038
                          bandwidth: 10000
                          resolution: 1080p
        '400':
          $ref: '#/components/responses/400'
  /:/unscrobble:
    put:
      tags:
      - Timeline
      operationId: putUnscrobble
      summary: Mark an item as unplayed
      description: 'Mark an item as unplayed. The client must provide either the `key` or `uri` query parameter

        This API does respond to the GET verb but applications should use PUT'
      parameters:
      - in: query
        name: identifier
        required: true
        schema:
          type: string
        description: The identifier of the media provider containing the media to rate.  Typically `com.plexapp.plugins.library`
      - in: query
        name: key
        required: false
        schema:
          type: string
        description: The key of the item to rate.  This is the `ratingKey` found in metadata items
      - in: query
        name: uri
        required: false
        schema:
          type: string
        description: The URI of the item to mark as played.  See intro for description of the URIs
      responses:
        '200':
          $ref: '#/components/responses/200'
        '400':
          description: Bad Request.  Can occur when parameters are of the wrong type, or missing
          content:
            text/html:
              examples:
                badRequest:
                  summary: A parameter has a bad value or required parameter is missing
                  value: <html><head><title>Bad Request</title></head><body><h1>400 Bad Request</h1></body></html>
        '404':
          description: Indicates that no library with the provide identifier can be found or no item can be found with the rating key
          content:
            text/html:
              examples:
                notFound:
                  summary: Not Found
                  value: <html><head><title>Not Found</title></head><body><h1>404 Not Found</h1></body></html>
components:
  schemas:
    MediaContainer:
      type: object
      properties:
        identifier:
          type: string
        size:
          type: integer
        totalSize:
          type: integer
          description: The total size of objects available.  Also provided in the X-Plex-Container-Total-Size header
        offset:
          type: integer
          description: The offset of where this container page starts among the total objects available.  Also provided in the X-Plex-Container-Start header
    serverConfiguration:
      allOf:
      - $ref: '#/components/schemas/MediaContainer'
      - type: object
        properties:
          allowCameraUpload:
            type: boolean
          allowChannelAccess:
            type: boolean
          allowMediaDeletion:
            type: boolean
          allowSharing:
            type: boolean
          allowSync:
            type: boolean
          allowTuners:
            type: boolean
          backgroundProcessing:
            type: boolean
          certificate:
            type: boolean
          companionProxy:
            type: boolean
          countryCode:
            type: string
          diagnostics:
            type: string
          eventStream:
            type: boolean
          friendlyName:
            type: string
          hubSearch:
            type: boolean
          itemClusters:
            type: boolean
          livetv:
            type: integer
            example: 7
          machineIdentifier:
            example: 0123456789abcdef0123456789abcdef012345678
          mediaProviders:
            type: boolean
          multiuser:
            type: boolean
          musicAnalysis:
            type: integer
            example: 2
          myPlex:
            type: boolean
          myPlexMappingState:
            example: mapped
          myPlexSigninState:
            example: ok
          myPlexSubscription:
            type: boolean
          myPlexUsername:
            type: string
          offlineTranscode:
            example: 1
          ownerFeatures:
            description: A comma-separated list of features which are enabled for the server owner
            type: string
          platform:
            type: string
          platformVersion:
            type: string
          pluginHost:
            type: boolean
          pushNotifications:
            type: boolean
          readOnlyLibraries:
            type: boolean
          streamingBrainABRVersion:
            type: integer
          streamingBrainVersion:
            type: integer
          sync:
            type: boolean
          transcoderActiveVideoSessions:
            type: integer
          transcoderAudio:
            type: boolean
          transcoderLyrics:
            type: boolean
          transcoderPhoto:
            type: boolean
          transcoderSubtitles:
            type: boolean
          transcoderVideo:
            type: boolean
          transcoderVideoBitrates:
            description: The suggested video quality bitrates to present to the user
          transcoderVideoQualities:
            type: string
          transcoderVideoResolutions:
            description: The suggested video resolutions to the above quality bitrates
          updatedAt:
            type: integer
          updater:
            type: boolean
          version:
            type: string
          voiceSearch:
            type: boolean
  responses:
    '200':
      description: OK
      content:
        text/html:
          examples:
            ok:
              summary: OK
              value: ''
    '400':
      description: Bad Request
      content:
        text/html:
          examples:
            badRequest:
              summary: A parameter has a bad value or required parameter is missing
              value: <html><head><title>Bad Request</title></head><body><h1>400 Bad Request</h1></body></html>
  securitySchemes:
    user_token:
      type: apiKey
      in: header
      name: X-Plex-Token
      description: The token which identifies the user accessing the PMS.  This is typically provided to the client by plex.tv. This can be either a traditional access token or a JWT token obtained through the JWT authentication flow.
x-tagGroups:
- name: General
  tags:
  - General
  - Library
  - Library Playlists
  - Library Collections
  - Status
  - Activities
  - Updater
  - Butler
  - Events
  - Log
  - Preferences
  - Download Queue
  - UltraBlur
  - Transcoder
- name: Media Provider
  tags:
  - Provider
  - Metadata Agents
  - Content
  - Hubs
  - Search
  - Rate
  - Playlist
  - Play Queue
  - Timeline
- name: DVR
  tags:
  - DVRs
  - Devices
  - EPG
  - Subscriptions
  - Live TV