Skip to main content
POST
/
playlists
/
{id}
/
copy
Copy a playlist into another.
curl --request POST \
  --url https://api.streamloop.app/v1/playlists/{id}/copy \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "targetPlaylistId": "<string>"
}
'
{
  "createdAt": "2023-11-07T05:31:56Z",
  "diff": {
    "added": [
      {
        "id": "<string>",
        "objectID": "<string>",
        "position": 123
      }
    ],
    "moved": [
      {
        "fromPosition": 123,
        "item": {
          "id": "<string>",
          "objectID": "<string>",
          "position": 123
        },
        "toPosition": 123
      }
    ],
    "removed": [
      {
        "itemId": "<string>",
        "objectId": "<string>",
        "position": 123
      }
    ],
    "unchanged": [
      {
        "id": "<string>",
        "objectID": "<string>",
        "position": 123
      }
    ]
  },
  "hasUnpublishedChanges": true,
  "id": "<string>",
  "liveItems": [
    {
      "itemId": "<string>",
      "objectId": "<string>",
      "position": 123
    }
  ],
  "liveVersion": 123,
  "streamID": "<string>",
  "updatedAt": "2023-11-07T05:31:56Z",
  "version": 123,
  "copiedFrom": "<string>",
  "items": [
    {
      "id": "<string>",
      "object": {
        "id": "<string>",
        "name": "<string>",
        "duration": 123
      },
      "objectID": "<string>",
      "position": 123
    }
  ]
}

Authorizations

Authorization
string
header
required

OAuth 2.1 authorization-code flow with PKCE.

Headers

Idempotency-Key
string

Optional client-generated key. A repeated request with the same key replays the original response (within 24h) instead of re-executing — safe retries.

Path Parameters

id
string
required

Resource identifier.

Body

application/json
targetPlaylistId
string
required

Response

Successful response.

createdAt
string<date-time>
required
diff
object
required

Snapshot-vs-draft diff (B-13 first-occurrence-by-objectId algorithm; zero-distance items go in unchanged, not moved; duplicate objectIds matched positionally). When no snapshot exists, diff = { unchanged: items, added: [], removed: [], moved: [] }.

hasUnpublishedChanges
boolean
required

snapshot != nil && Playlist.version > snapshot.version. Returns false during the B-11 STREAMING+no-snapshot window — deliberate: the stream is live but nothing has been published yet.

id
string
required
kind
enum<string>
required
Available options:
video,
audio
liveItems
object[]
required

Projected from PlaylistSnapshot.items JSON (NB-12) — never FK-hydrated against the live PlaylistItem table. Empty list during the B-11 STREAMING+no-snapshot window.

liveVersion
integer
required

PlaylistSnapshot.version — Playlist.version frozen at the last LIVE write. Returns 0 when no snapshot exists OR during the B-11 STREAMING+no-snapshot transient window (WriteInitialPlaylistSnapshot retry).

mode
enum<string>
required
Available options:
sequential,
shuffle
publishStatus
enum<string>
required

Workflow-state derivation. NB-13: PREPARING wins over PENDING even when a concurrent edit advances Playlist.version while a publish is preparing.

Available options:
IDLE,
PENDING,
PREPARING,
FAILED,
NOT_LIVE
streamID
string
required
updatedAt
string<date-time>
required
version
integer
required

Bumped by 1 per committed spec mutation batch. Used for optimistic concurrency and as the snapshot handle for PreparePlaylistWorkflow.

copiedFrom
string | null
items
object[]