{
  "components": {
    "schemas": {
      "AddStreamDestinationRequest": {
        "properties": {
          "destinationId": {
            "type": "string"
          }
        },
        "required": [
          "destinationId"
        ],
        "type": "object"
      },
      "ApplyPlaylistOperationsPayload": {
        "properties": {
          "playlist": {
            "properties": {
              "hasUnpublishedChanges": {
                "description": "The draft has edits the live stream does not play yet (publish to put them on air).",
                "type": "boolean"
              },
              "id": {
                "type": "string"
              },
              "items": {
                "items": {
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "objectID": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "position": {
                      "description": "0-based; positions for a playlist form {0..N-1} exactly. Enforced by mutation layer (full-rewrite) and unique index.",
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "position"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "mode": {
                "enum": [
                  "sequential",
                  "shuffle"
                ],
                "type": "string"
              },
              "publishStatus": {
                "description": "Where the latest publish is.",
                "enum": [
                  "IDLE",
                  "PENDING",
                  "PREPARING",
                  "FAILED",
                  "NOT_LIVE"
                ],
                "type": "string"
              },
              "streamID": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "version": {
                "description": "The draft's version, bumped by 1 per committed edit batch. Pass it back to playlist edits for optimistic concurrency.",
                "type": "integer"
              }
            },
            "required": [
              "hasUnpublishedChanges",
              "id",
              "mode",
              "publishStatus",
              "version"
            ],
            "type": "object"
          }
        },
        "required": [
          "playlist"
        ],
        "type": "object"
      },
      "ApplyPlaylistOperationsRequest": {
        "properties": {
          "basedOnVersion": {
            "description": "If set, reject the batch with CONFLICT when playlists.version has\nadvanced past this value.",
            "type": [
              "integer",
              "null"
            ]
          },
          "operations": {
            "items": {
              "properties": {
                "addObjects": {
                  "properties": {
                    "index": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "objectIds": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "position": {
                      "enum": [
                        "START",
                        "END",
                        "INDEX"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "objectIds",
                    "position"
                  ],
                  "type": "object"
                },
                "removeItems": {
                  "properties": {
                    "itemIds": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "itemIds"
                  ],
                  "type": "object"
                },
                "reorderItems": {
                  "properties": {
                    "moves": {
                      "items": {
                        "properties": {
                          "index": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "itemId": {
                            "type": "string"
                          },
                          "position": {
                            "enum": [
                              "START",
                              "END",
                              "INDEX"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "itemId",
                          "position"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "moves"
                  ],
                  "type": "object"
                },
                "updateSettings": {
                  "properties": {
                    "mode": {
                      "enum": [
                        "sequential",
                        "shuffle"
                      ],
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "playlistId": {
            "type": "string"
          }
        },
        "required": [
          "operations",
          "playlistId"
        ],
        "type": "object"
      },
      "BatchOperation": {
        "additionalProperties": false,
        "description": "One ordinary REST operation. The path is relative to /v1; nested batches are forbidden.",
        "properties": {
          "body": {
            "description": "JSON request body for POST, PATCH or PUT operations."
          },
          "id": {
            "description": "Caller-supplied correlation ID, unique within this batch.",
            "minLength": 1,
            "type": "string"
          },
          "idempotencyKey": {
            "description": "Per-operation idempotency key for POST or PATCH. The outer request key is not inherited.",
            "type": "string"
          },
          "method": {
            "enum": [
              "GET",
              "POST",
              "PATCH",
              "PUT",
              "DELETE"
            ],
            "type": "string"
          },
          "path": {
            "description": "Path relative to /v1, including any query string (for example /streams?limit=10).",
            "pattern": "^/",
            "type": "string"
          }
        },
        "required": [
          "id",
          "method",
          "path"
        ],
        "type": "object"
      },
      "BatchResult": {
        "additionalProperties": false,
        "description": "The independent result of one operation. Results preserve input order.",
        "properties": {
          "body": {
            "description": "Decoded JSON response body, or a string for a non-JSON response."
          },
          "headers": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          },
          "id": {
            "type": "string"
          },
          "status": {
            "maximum": 599,
            "minimum": 100,
            "type": "integer"
          }
        },
        "required": [
          "id",
          "status"
        ],
        "type": "object"
      },
      "BillingOverview": {
        "properties": {
          "billing": {
            "description": "The selected workspace's credit wallet, shared by every member. An explicit\nworkspaceId selects another workspace you are a member of. Null when no\nworkspace is selected.",
            "properties": {
              "balance": {
                "description": "Dollar balance computed from credits (creditsLeft / 1,000,000)",
                "type": "number"
              },
              "creditsLeft": {
                "type": "integer"
              },
              "eligibleForFreeCredits": {
                "description": "Whether this user can still claim the one-time $5 signup credits.",
                "type": "boolean"
              },
              "goodStanding": {
                "type": "boolean"
              },
              "id": {
                "type": "string"
              }
            },
            "required": [
              "balance",
              "creditsLeft",
              "eligibleForFreeCredits",
              "goodStanding",
              "id"
            ],
            "type": [
              "object",
              "null"
            ]
          },
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      },
      "CheckoutLink": {
        "properties": {
          "checkoutUrl": {
            "description": "Empty unless status is ACTION_REQUIRED.",
            "type": "string"
          },
          "credits": {
            "description": "Credits that will be added to the account after payment",
            "type": "integer"
          },
          "sessionId": {
            "type": "string"
          },
          "status": {
            "enum": [
              "COMPLETED",
              "PENDING",
              "ACTION_REQUIRED"
            ],
            "type": "string"
          }
        },
        "required": [
          "checkoutUrl",
          "credits",
          "sessionId",
          "status"
        ],
        "type": "object"
      },
      "CopyPlaylistPayload": {
        "properties": {
          "target": {
            "properties": {
              "id": {
                "type": "string"
              },
              "items": {
                "items": {
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "objectID": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "position": {
                      "description": "0-based; positions for a playlist form {0..N-1} exactly. Enforced by mutation layer (full-rewrite) and unique index.",
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "position"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "mode": {
                "enum": [
                  "sequential",
                  "shuffle"
                ],
                "type": "string"
              },
              "streamID": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "version": {
                "description": "The draft's version, bumped by 1 per committed edit batch. Pass it back to playlist edits for optimistic concurrency.",
                "type": "integer"
              }
            },
            "required": [
              "id",
              "mode",
              "version"
            ],
            "type": "object"
          }
        },
        "required": [
          "target"
        ],
        "type": "object"
      },
      "CopyPlaylistRequest": {
        "properties": {
          "targetPlaylistId": {
            "type": "string"
          }
        },
        "required": [
          "targetPlaylistId"
        ],
        "type": "object"
      },
      "CreatePlaylistRequest": {
        "properties": {
          "kind": {
            "enum": [
              "video",
              "audio"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "sceneId": {
            "description": "The scene that owns the playlist (scn_*), in the active workspace.",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "name",
          "sceneId"
        ],
        "type": "object"
      },
      "CreateRtmpDestinationRequest": {
        "properties": {
          "name": {
            "type": "string"
          },
          "rtmpKey": {
            "type": "string"
          },
          "rtmpUrl": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "rtmpKey",
          "rtmpUrl"
        ],
        "type": "object"
      },
      "CreateStreamRequest": {
        "properties": {
          "framerate": {
            "enum": [
              "f_24",
              "f_25",
              "f_30",
              "f_60"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "quality": {
            "enum": [
              "q_720p",
              "q_1080p",
              "q_1440p",
              "q_2160p"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "runBackupStream": {
            "description": "Also publish to YouTube's backup ingest, for redundancy. Doubles the streaming cost while live.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "storageBackend": {
            "description": "Storage tier for this stream's media. 'standard' suits typical playlists and is included. 'large' is for big playlists: storage is provisioned to fit your content and grows as you add to it, billed per GiB-month. Takes effect at the next stream start.",
            "enum": [
              "standard",
              "large"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "streamDuration": {
            "description": "Stream duration in seconds. 0 = never expires. Copied from user default on creation.",
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "CreateUploadFromLinkRequest": {
        "properties": {
          "selections": {
            "items": {
              "description": "One asset and quality pair confirmed from ExternalLinkContents, optionally narrowed to a\ntime range of the source.\n\nThe same asset may appear several times with different ranges: each selection produces its\nown upload, so importing two clips of one video (or re-importing a different range of a\nvideo already imported) is a matter of repeating the asset with a new range.",
              "properties": {
                "assetId": {
                  "type": "string"
                },
                "endSeconds": {
                  "description": "Import only up to this offset in the source, in seconds. Null (the default) runs to the\nend. Ranges past the end of the source are truncated by the provider.",
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "preciseCut": {
                  "description": "Cut exactly at the requested offsets instead of snapping to the nearest keyframes. This\nre-encodes around each cut, so the import is markedly slower; the default (false) is a\nstream copy whose start may include up to a few seconds of preceding video. Ignored when\nno range is given.",
                  "type": [
                    "boolean",
                    "null"
                  ]
                },
                "qualityId": {
                  "type": "string"
                },
                "startSeconds": {
                  "description": "Import only from this offset in the source, in seconds. Null (the default) starts at the\nbeginning. Must be \u003c endSeconds and \u003c the item's durationSeconds when it is known.",
                  "type": [
                    "number",
                    "null"
                  ]
                }
              },
              "required": [
                "assetId",
                "qualityId"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "selections",
          "url"
        ],
        "type": "object"
      },
      "CreateUploadRequest": {
        "properties": {
          "duration": {
            "type": [
              "integer",
              "null"
            ]
          },
          "fileSize": {
            "type": [
              "integer",
              "null"
            ]
          },
          "fps": {
            "type": [
              "number",
              "null"
            ]
          },
          "hasAudio": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "hasVideo": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "height": {
            "type": [
              "integer",
              "null"
            ]
          },
          "isDeleted": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "mimeType": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "orientation": {
            "type": [
              "integer",
              "null"
            ]
          },
          "path": {
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "enum": [
              "audio",
              "video",
              "image"
            ],
            "type": "string"
          },
          "width": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "mimeType",
          "name",
          "type"
        ],
        "type": "object"
      },
      "CryptoCurrency": {
        "properties": {
          "chainId": {
            "description": "EVM chain ID a WalletConnect/wagmi client should switch to before signing.\nNull for non-EVM chains (Solana, Tron, Bitcoin, TON, …) — those need\ntheir own connector libraries.",
            "type": [
              "integer",
              "null"
            ]
          },
          "contractAddress": {
            "description": "Token contract address for ERC20-style tokens on EVM chains\n(and SPL mint for Solana). Null for native coins (ETH, SOL, MATIC, BTC, …)\nwhere a wallet sends a plain transfer instead of calling a contract.",
            "type": [
              "string",
              "null"
            ]
          },
          "decimals": {
            "description": "Decimals for unit conversion. ERC20 tokens vary (USDT=6, DAI=18); native\ncoins follow chain convention (ETH=18, SOL=9, BTC=8). Defaults to 18 when\nunknown so EVM transfers stay safe.",
            "type": "integer"
          },
          "icon": {
            "description": "SVG icon URL.",
            "type": "string"
          },
          "id": {
            "description": "0xProcessing currency identifier, e.g. \"USDT (TRC20)\" or \"BTC\".",
            "type": "string"
          },
          "name": {
            "description": "Human-readable name from manifest, e.g. \"Tether\".",
            "type": "string"
          },
          "network": {
            "description": "Network code from the manifest, e.g. \"TRC20\", \"ERC20\", \"POLYGON\", \"SOL\".",
            "type": "string"
          },
          "rateUSD": {
            "description": "Price of 1 unit in USD (from Binance; 1.0 for stablecoins).",
            "type": "number"
          },
          "symbol": {
            "description": "Base symbol, e.g. \"USDT\".",
            "type": "string"
          },
          "transferKind": {
            "description": "How a client should construct the payment transaction.",
            "enum": [
              "EVM_NATIVE",
              "EVM_ERC20",
              "NON_EVM"
            ],
            "type": "string"
          }
        },
        "required": [
          "decimals",
          "icon",
          "id",
          "name",
          "network",
          "rateUSD",
          "symbol",
          "transferKind"
        ],
        "type": "object"
      },
      "CryptoDepositAddress": {
        "properties": {
          "address": {
            "description": "Blockchain deposit address.",
            "type": "string"
          },
          "id": {
            "description": "0xProcessing currency identifier used to create this wallet.",
            "type": "string"
          },
          "network": {
            "description": "Network name, e.g. \"TRC20\", \"ERC20\", \"Bitcoin\", \"Solana\".",
            "type": "string"
          },
          "tag": {
            "description": "Memo/tag required for TON, XRP, etc. Null if not required.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "address",
          "id",
          "network"
        ],
        "type": "object"
      },
      "Destination": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "kind": {
            "enum": [
              "custom_rtmp",
              "youtube"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "rtmpURL": {
            "description": "Full RTMP ingest URL, e.g. rtmp://live.twitch.tv/app. Null for non-rtmp kinds.",
            "type": [
              "string",
              "null"
            ]
          },
          "rtmpUrlMasked": {
            "description": "Display-safe RTMP publish URL with the stream key redacted.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "active",
              "needs_reauth",
              "revoked",
              "disabled"
            ],
            "type": "string"
          }
        },
        "required": [
          "createdAt",
          "id",
          "kind",
          "name",
          "status"
        ],
        "type": "object"
      },
      "DestinationList": {
        "description": "A page of destination items.",
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/DestinationSummary"
            },
            "type": "array"
          },
          "page": {
            "$ref": "#/components/schemas/Page"
          }
        },
        "required": [
          "data",
          "page"
        ],
        "type": "object"
      },
      "DestinationSummary": {
        "properties": {
          "archivedAt": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "kind": {
            "enum": [
              "custom_rtmp",
              "youtube"
            ],
            "type": "string"
          },
          "lastUsedAt": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "rtmpURL": {
            "description": "Full RTMP ingest URL, e.g. rtmp://live.twitch.tv/app. Null for non-rtmp kinds.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "active",
              "needs_reauth",
              "revoked",
              "disabled"
            ],
            "type": "string"
          },
          "ytChannelTitleCached": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "createdAt",
          "id",
          "kind",
          "name",
          "status"
        ],
        "type": "object"
      },
      "InvoiceList": {
        "description": "A page of invoice items.",
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/InvoiceSummary"
            },
            "type": "array"
          },
          "page": {
            "$ref": "#/components/schemas/Page"
          }
        },
        "required": [
          "data",
          "page"
        ],
        "type": "object"
      },
      "InvoiceSummary": {
        "properties": {
          "cost": {
            "type": "integer"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "credits": {
            "type": "integer"
          },
          "currency": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "method": {
            "type": "string"
          },
          "receiptURL": {
            "description": "Receipt/invoice download URL from the payment provider. Persisted at webhook time when available, otherwise fetched lazily on first access.",
            "type": [
              "string",
              "null"
            ]
          },
          "remainingCredits": {
            "type": "integer"
          },
          "state": {
            "enum": [
              "cancelled",
              "pending",
              "paid"
            ],
            "type": "string"
          },
          "type": {
            "enum": [
              "credit_purchase",
              "usage_summary",
              "credit_grant",
              "subscription_charge",
              "trial_charge",
              "auto_reload"
            ],
            "type": "string"
          }
        },
        "required": [
          "cost",
          "createdAt",
          "credits",
          "currency",
          "id",
          "method",
          "remainingCredits",
          "state",
          "type"
        ],
        "type": "object"
      },
      "Page": {
        "description": "Cursor-pagination metadata.",
        "properties": {
          "hasMore": {
            "description": "Whether another page is available.",
            "type": "boolean"
          },
          "nextCursor": {
            "description": "Cursor for the next page, or null on the last page.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "nextCursor",
          "hasMore"
        ],
        "type": "object"
      },
      "Playlist": {
        "properties": {
          "copiedFrom": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "diff": {
            "description": "How the draft differs from what plays live. An item at the same position is\n`unchanged`, not `moved`. When nothing is live, every item is `unchanged`.",
            "properties": {
              "added": {
                "items": {
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "objectID": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "position": {
                      "description": "0-based; positions for a playlist form {0..N-1} exactly. Enforced by mutation layer (full-rewrite) and unique index.",
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "position"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "moved": {
                "items": {
                  "properties": {
                    "fromPosition": {
                      "type": "integer"
                    },
                    "item": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "objectID": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "position": {
                          "description": "0-based; positions for a playlist form {0..N-1} exactly. Enforced by mutation layer (full-rewrite) and unique index.",
                          "type": "integer"
                        }
                      },
                      "required": [
                        "id",
                        "position"
                      ],
                      "type": "object"
                    },
                    "toPosition": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "fromPosition",
                    "item",
                    "toPosition"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "removed": {
                "description": "Live items the draft no longer has.",
                "items": {
                  "description": "An item as the live stream plays it. The draft item it came from may since\nhave been removed.",
                  "properties": {
                    "itemId": {
                      "description": "Playlist item id (plitm_…) at the time it went live.",
                      "type": "string"
                    },
                    "objectId": {
                      "description": "Media id (obj_…).",
                      "type": "string"
                    },
                    "position": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "itemId",
                    "objectId",
                    "position"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "unchanged": {
                "items": {
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "objectID": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "position": {
                      "description": "0-based; positions for a playlist form {0..N-1} exactly. Enforced by mutation layer (full-rewrite) and unique index.",
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "position"
                  ],
                  "type": "object"
                },
                "type": "array"
              }
            },
            "required": [
              "added",
              "moved",
              "removed",
              "unchanged"
            ],
            "type": "object"
          },
          "hasUnpublishedChanges": {
            "description": "The draft has edits the live stream does not play yet (publish to put them on air).",
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "items": {
            "items": {
              "properties": {
                "id": {
                  "type": "string"
                },
                "object": {
                  "properties": {
                    "duration": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "enum": [
                        "audio",
                        "video",
                        "image"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "type"
                  ],
                  "type": [
                    "object",
                    "null"
                  ]
                },
                "objectID": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "position": {
                  "description": "0-based; positions for a playlist form {0..N-1} exactly. Enforced by mutation layer (full-rewrite) and unique index.",
                  "type": "integer"
                }
              },
              "required": [
                "id",
                "position"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "kind": {
            "enum": [
              "video",
              "audio"
            ],
            "type": "string"
          },
          "liveItems": {
            "description": "The items the live stream plays, in order (empty when nothing is live yet).",
            "items": {
              "description": "An item as the live stream plays it. The draft item it came from may since\nhave been removed.",
              "properties": {
                "itemId": {
                  "description": "Playlist item id (plitm_…) at the time it went live.",
                  "type": "string"
                },
                "objectId": {
                  "description": "Media id (obj_…).",
                  "type": "string"
                },
                "position": {
                  "type": "integer"
                }
              },
              "required": [
                "itemId",
                "objectId",
                "position"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "liveVersion": {
            "description": "The draft version the live stream plays (0 when nothing is live yet).",
            "type": "integer"
          },
          "mode": {
            "enum": [
              "sequential",
              "shuffle"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "publishStatus": {
            "description": "Where the latest publish is.",
            "enum": [
              "IDLE",
              "PENDING",
              "PREPARING",
              "FAILED",
              "NOT_LIVE"
            ],
            "type": "string"
          },
          "sceneId": {
            "description": "The scene that owns this playlist (scn_…); null for a stream playlist.",
            "type": [
              "string",
              "null"
            ]
          },
          "streamID": {
            "type": [
              "string",
              "null"
            ]
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          },
          "version": {
            "description": "The draft's version, bumped by 1 per committed edit batch. Pass it back to playlist edits for optimistic concurrency.",
            "type": "integer"
          }
        },
        "required": [
          "createdAt",
          "diff",
          "hasUnpublishedChanges",
          "id",
          "kind",
          "liveItems",
          "liveVersion",
          "mode",
          "name",
          "publishStatus",
          "updatedAt",
          "version"
        ],
        "type": "object"
      },
      "PlaylistList": {
        "description": "A page of playlist items.",
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/PlaylistSummary"
            },
            "type": "array"
          },
          "page": {
            "$ref": "#/components/schemas/Page"
          }
        },
        "required": [
          "data",
          "page"
        ],
        "type": "object"
      },
      "PlaylistSummary": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "kind": {
            "enum": [
              "video",
              "audio"
            ],
            "type": "string"
          },
          "mode": {
            "enum": [
              "sequential",
              "shuffle"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "sceneId": {
            "description": "The scene that owns this playlist (scn_…); null for a stream playlist.",
            "type": [
              "string",
              "null"
            ]
          },
          "streamID": {
            "type": [
              "string",
              "null"
            ]
          },
          "version": {
            "description": "The draft's version, bumped by 1 per committed edit batch. Pass it back to playlist edits for optimistic concurrency.",
            "type": "integer"
          }
        },
        "required": [
          "createdAt",
          "id",
          "kind",
          "mode",
          "name",
          "version"
        ],
        "type": "object"
      },
      "Problem": {
        "additionalProperties": {
          "description": "Details of the refusal beyond its code, e.g. reason."
        },
        "description": "RFC 7807 problem-details error body.",
        "properties": {
          "code": {
            "description": "A stable, machine-readable error code: branch on it, not on the HTTP status. 400: BAD_REQUEST, INVALID_BATCH, WORKSPACE_REQUIRED. 401: UNAUTHENTICATED. 402: INSUFFICIENT_CREDITS. 403: FORBIDDEN, INSUFFICIENT_SCOPE, MULTISTREAM_NOT_ENABLED. 404: NOT_FOUND. 405: METHOD_NOT_ALLOWED. 409: CONFLICT, DESTINATION_DUPLICATE, DESTINATION_LIMIT, IMMUTABLE_WHILE_LIVE, IN_USE, LAST_DESTINATION, MIRROR_DESTINATION_CHANGE_BLOCKED, NOT_LIVE, STALE_DRAFT, STREAM_ILLEGAL_TRANSITION, STREAM_LIVE, UPLOAD_ALREADY_COMPLETED, UPLOAD_INCOMPLETE, YOUTUBE_DESTINATION_LIMIT. 410: GONE. 422: DESTINATION_INCOMPATIBLE, FILE_TOO_LARGE, IDEMPOTENCY_KEY_REUSED, INVALID_INPUT, SCENE_ASSET_MISSING, SCENE_MISSING, SCENE_NOT_PUBLISHED, SCENE_PLAYLISTS_UNSUPPORTED, SCENE_PLAYLIST_MISSING, SCENE_QUALITY_UNSUPPORTED, STREAM_GUARD_FAILED, UNSUPPORTED_TYPE, UPLOAD_REMOVED. 429: RATE_LIMITED. 500: INTERNAL. 502: UPSTREAM_ERROR. 503: EXTERNAL_UPLOAD_ENQUEUE_FAILED, UNAVAILABLE. Other codes: 404 for *_NOT_FOUND, 403 for *_FORBIDDEN, 503 for *_UNAVAILABLE, else 422. 502 UPSTREAM_ERROR is an unexpected failure.",
            "type": "string"
          },
          "detail": {
            "description": "A human-readable explanation specific to this occurrence.",
            "type": "string"
          },
          "status": {
            "description": "The HTTP status code.",
            "type": "integer"
          },
          "title": {
            "description": "A short, human-readable summary of the problem.",
            "type": "string"
          },
          "type": {
            "description": "A URI reference identifying the problem type.",
            "format": "uri-reference",
            "type": "string"
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "code"
        ],
        "type": "object"
      },
      "PublishPlaylistPayload": {
        "properties": {
          "playlist": {
            "properties": {
              "hasUnpublishedChanges": {
                "description": "The draft has edits the live stream does not play yet (publish to put them on air).",
                "type": "boolean"
              },
              "id": {
                "type": "string"
              },
              "liveVersion": {
                "description": "The draft version the live stream plays (0 when nothing is live yet).",
                "type": "integer"
              },
              "publishStatus": {
                "description": "Where the latest publish is.",
                "enum": [
                  "IDLE",
                  "PENDING",
                  "PREPARING",
                  "FAILED",
                  "NOT_LIVE"
                ],
                "type": "string"
              },
              "streamID": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "version": {
                "description": "The draft's version, bumped by 1 per committed edit batch. Pass it back to playlist edits for optimistic concurrency.",
                "type": "integer"
              }
            },
            "required": [
              "hasUnpublishedChanges",
              "id",
              "liveVersion",
              "publishStatus",
              "version"
            ],
            "type": "object"
          },
          "snapshot": {
            "description": "A version of a playlist as it went live.",
            "properties": {
              "frozenAt": {
                "format": "date-time",
                "type": "string"
              },
              "id": {
                "description": "typeid psnap_*",
                "type": "string"
              },
              "items": {
                "items": {
                  "description": "An item as the live stream plays it. The draft item it came from may since\nhave been removed.",
                  "properties": {
                    "itemId": {
                      "description": "Playlist item id (plitm_…) at the time it went live.",
                      "type": "string"
                    },
                    "objectId": {
                      "description": "Media id (obj_…).",
                      "type": "string"
                    },
                    "position": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "itemId",
                    "objectId",
                    "position"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "version": {
                "type": "integer"
              }
            },
            "required": [
              "frozenAt",
              "id",
              "items",
              "version"
            ],
            "type": [
              "object",
              "null"
            ]
          }
        },
        "required": [
          "playlist"
        ],
        "type": "object"
      },
      "PublishPlaylistRequest": {
        "properties": {
          "expectedDraftVersion": {
            "description": "The draft version you reviewed (Playlist.version). A newer draft is refused\nwith STALE_DRAFT and its currentVersion: re-read the playlist and retry.",
            "type": "integer"
          },
          "playlistId": {
            "type": "string"
          }
        },
        "required": [
          "expectedDraftVersion",
          "playlistId"
        ],
        "type": "object"
      },
      "RemoveUploadsRequest": {
        "properties": {
          "ids": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "ids"
        ],
        "type": "object"
      },
      "RemoveUploadsResult": {
        "properties": {
          "refused": {
            "items": {
              "properties": {
                "id": {
                  "type": "string"
                },
                "reason": {
                  "enum": [
                    "NOT_FOUND",
                    "IN_USE",
                    "UNSUPPORTED_TYPE",
                    "UPLOAD_INCOMPLETE",
                    "FAILED"
                  ],
                  "type": "string"
                }
              },
              "required": [
                "id",
                "reason"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "removedIds": {
            "description": "Ids now removed, including ones that already were.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "refused",
          "removedIds"
        ],
        "type": "object"
      },
      "ScheduleStreamRequest": {
        "properties": {
          "days": {
            "items": {
              "enum": [
                "SUNDAY",
                "MONDAY",
                "TUESDAY",
                "WEDNESDAY",
                "THURSDAY",
                "FRIDAY",
                "SATURDAY"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "repeat": {
            "enum": [
              "none",
              "daily",
              "weekly"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "scheduleEndAt": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "scheduleStartAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "scheduleStartAt"
        ],
        "type": "object"
      },
      "SetStreamDestinationEnabledRequest": {
        "properties": {
          "enabled": {
            "type": "boolean"
          }
        },
        "required": [
          "enabled"
        ],
        "type": "object"
      },
      "SetStreamSceneRequest": {
        "properties": {
          "sceneId": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "Status": {
        "properties": {
          "service": {
            "type": "string"
          },
          "status": {
            "description": "operational | degraded | down",
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "status"
        ],
        "type": "object"
      },
      "Stream": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "destinations": {
            "description": "Outputs in creation order.",
            "items": {
              "properties": {
                "createdAt": {
                  "format": "date-time",
                  "type": "string"
                },
                "destination": {
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "kind": {
                      "enum": [
                        "custom_rtmp",
                        "youtube"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "name"
                  ],
                  "type": "object"
                },
                "destinationID": {
                  "type": "string"
                },
                "disabledReason": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "enabled": {
                  "type": "boolean"
                },
                "state": {
                  "enum": [
                    "idle",
                    "connecting",
                    "live",
                    "reconnecting",
                    "cooldown",
                    "paused",
                    "failed"
                  ],
                  "type": "string"
                },
                "stateReason": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "stateSince": {
                  "format": "date-time",
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "createdAt",
                "destination",
                "destinationID",
                "enabled",
                "state"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "framerate": {
            "enum": [
              "f_24",
              "f_25",
              "f_30",
              "f_60"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "quality": {
            "enum": [
              "q_720p",
              "q_1080p",
              "q_1440p",
              "q_2160p"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "runBackupStream": {
            "description": "Also publish to YouTube's backup ingest, for redundancy. Doubles the streaming cost while live.",
            "type": "boolean"
          },
          "scene": {
            "description": "The scene a stream plays (a live, designed stream) instead of its video\nplaylist. Scenes are made and published with the Scenes API — its OpenAPI\ndocument is GET /v1/scenes/openapi.json. Publish the scene before attaching\nit with PUT /v1/streams/{id}/scene.",
            "properties": {
              "id": {
                "description": "The scene's id (scn_…).",
                "type": "string"
              }
            },
            "required": [
              "id"
            ],
            "type": [
              "object",
              "null"
            ]
          },
          "scheduleEndAt": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "scheduleRepeat": {
            "enum": [
              "none",
              "daily",
              "weekly"
            ],
            "type": "string"
          },
          "scheduleRepeatDays": {
            "description": "Weekdays a `weekly` window starts on, as the UTC weekday of `scheduleStartAt`.\nEmpty = every 7 days from the anchor. Always empty unless `scheduleRepeat` is `weekly`.",
            "items": {
              "enum": [
                "SUNDAY",
                "MONDAY",
                "TUESDAY",
                "WEDNESDAY",
                "THURSDAY",
                "FRIDAY",
                "SATURDAY"
              ],
              "type": "string"
            },
            "type": "array"
          },
          "scheduleStartAt": {
            "format": "date-time",
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "enum": [
              "draft",
              "invalid",
              "scheduled",
              "preparing",
              "activating",
              "active",
              "failing",
              "failed",
              "stopping",
              "stopped"
            ],
            "type": "string"
          },
          "storageBackend": {
            "description": "Storage tier for this stream's media. 'standard' suits typical playlists and is included. 'large' is for big playlists: storage is provisioned to fit your content and grows as you add to it, billed per GiB-month. Takes effect at the next stream start.",
            "enum": [
              "standard",
              "large"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "streamDuration": {
            "description": "Stream duration in seconds. 0 = never expires. Copied from user default on creation.",
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "state"
        ],
        "type": "object"
      },
      "StreamDestinations": {
        "properties": {
          "destinations": {
            "description": "Outputs in creation order.",
            "items": {
              "properties": {
                "createdAt": {
                  "format": "date-time",
                  "type": "string"
                },
                "destination": {
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "kind": {
                      "enum": [
                        "custom_rtmp",
                        "youtube"
                      ],
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "name"
                  ],
                  "type": "object"
                },
                "destinationID": {
                  "type": "string"
                },
                "disabledReason": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "enabled": {
                  "type": "boolean"
                },
                "state": {
                  "enum": [
                    "idle",
                    "connecting",
                    "live",
                    "reconnecting",
                    "cooldown",
                    "paused",
                    "failed"
                  ],
                  "type": "string"
                },
                "stateReason": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "stateSince": {
                  "format": "date-time",
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "createdAt",
                "destination",
                "destinationID",
                "enabled",
                "state"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "id": {
            "type": "string"
          }
        },
        "required": [
          "destinations",
          "id"
        ],
        "type": "object"
      },
      "StreamList": {
        "description": "A page of stream items.",
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/StreamSummary"
            },
            "type": "array"
          },
          "page": {
            "$ref": "#/components/schemas/Page"
          }
        },
        "required": [
          "data",
          "page"
        ],
        "type": "object"
      },
      "StreamLiveStats": {
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "youtubeLiveStats": {
            "description": "Live YouTube viewer + cumulative stats for this stream. Returns null\nwhen the stream's destination isn't a YouTube channel, or when no\nbroadcast has been provisioned yet (the row is still\npre-EnsureBroadcast). Otherwise routes through destinations-gateway,\nwhich caches the underlying videos.list response in JetStream KV\nfor 10 minutes.",
            "properties": {
              "concurrentViewers": {
                "description": "Concurrent live viewers from videos.list(part=liveStreamingDetails). Always 0 when the broadcast is not LIVE.",
                "type": "integer"
              },
              "fetchedAt": {
                "description": "Server time the gateway last hit YouTube for this row. Stale up to ~10 minutes; surface as 'updated …' in the UI.",
                "format": "date-time",
                "type": "string"
              },
              "lifecycle": {
                "description": "Current YouTube broadcast lifecycle (CREATED / READY / TESTING / LIVE / COMPLETE / REVOKED / ERRORED). Use this to gate UI: concurrentViewers is only meaningful while LIVE.",
                "enum": [
                  "CREATED",
                  "READY",
                  "TESTING",
                  "LIVE",
                  "COMPLETE",
                  "REVOKED",
                  "ERRORED",
                  "UNSPECIFIED"
                ],
                "type": "string"
              },
              "likeCount": {
                "description": "Cumulative likes from videos.list(part=statistics). Survives post-VOD.",
                "type": "integer"
              },
              "mirrorLastError": {
                "description": "Why the last attempt to mirror the schedule onto YouTube failed, as a code\n(e.g. YOUTUBE_REAUTH_REQUIRED, YOUTUBE_QUOTA_EXCEEDED, YOUTUBE_CHANNEL_BUSY,\nMIRROR_NOT_POSSIBLE, STUDIO_DRIFT); null on MIRRORED / IDLE.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "mirrorStatus": {
                "description": "Current state of the YouTube schedule mirror for this stream. IDLE\nwhen the toggle is off; PENDING from intent receipt until the first\nsuccessful YouTube call returns; MIRRORED on success; OUT_OF_SYNC /\nNEEDS_REAUTH / BLOCKED on the corresponding terminal failures.\nSee MirrorStatus for full semantics.",
                "enum": [
                  "IDLE",
                  "PENDING",
                  "MIRRORED",
                  "OUT_OF_SYNC",
                  "NEEDS_REAUTH",
                  "BLOCKED"
                ],
                "type": "string"
              },
              "totalViews": {
                "description": "Cumulative video views from videos.list(part=statistics). Survives post-VOD.",
                "type": "integer"
              },
              "watchUrl": {
                "description": "Stable public watch URL of the broadcast on YouTube.",
                "type": "string"
              }
            },
            "required": [
              "concurrentViewers",
              "fetchedAt",
              "lifecycle",
              "likeCount",
              "mirrorStatus",
              "totalViews",
              "watchUrl"
            ],
            "type": [
              "object",
              "null"
            ]
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      },
      "StreamReadiness": {
        "properties": {
          "issues": {
            "items": {
              "properties": {
                "code": {
                  "type": "string"
                },
                "destinationId": {
                  "description": "The stream destination the issue is about (dest_…); null for an issue of the stream itself.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "error": {
                  "type": "string"
                },
                "path": {
                  "enum": [
                    "YOUTUBE",
                    "VALIDATION"
                  ],
                  "type": "string"
                },
                "stage": {
                  "enum": [
                    "PREFLIGHT"
                  ],
                  "type": "string"
                },
                "suggestion": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "code",
                "error",
                "path",
                "stage"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "ready": {
            "type": "boolean"
          }
        },
        "required": [
          "issues",
          "ready"
        ],
        "type": "object"
      },
      "StreamSummary": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "enum": [
              "draft",
              "invalid",
              "scheduled",
              "preparing",
              "activating",
              "active",
              "failing",
              "failed",
              "stopping",
              "stopped"
            ],
            "type": "string"
          }
        },
        "required": [
          "createdAt",
          "id",
          "state"
        ],
        "type": "object"
      },
      "TopUpUsingCardLinkRequest": {
        "properties": {
          "amountCents": {
            "type": "integer"
          }
        },
        "required": [
          "amountCents"
        ],
        "type": "object"
      },
      "UpdateStreamRequest": {
        "properties": {
          "clearStreamDuration": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "framerate": {
            "enum": [
              "f_24",
              "f_25",
              "f_30",
              "f_60"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "quality": {
            "enum": [
              "q_720p",
              "q_1080p",
              "q_1440p",
              "q_2160p"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "runBackupStream": {
            "description": "Also publish to YouTube's backup ingest, for redundancy. Doubles the streaming cost while live.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "storageBackend": {
            "description": "Storage tier for this stream's media. 'standard' suits typical playlists and is included. 'large' is for big playlists: storage is provisioned to fit your content and grows as you add to it, billed per GiB-month. Takes effect at the next stream start.",
            "enum": [
              "standard",
              "large"
            ],
            "type": [
              "string",
              "null"
            ]
          },
          "streamDuration": {
            "description": "Stream duration in seconds. 0 = never expires. Copied from user default on creation.",
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "Upload": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "downloadUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "duration": {
            "type": [
              "integer",
              "null"
            ]
          },
          "externalSource": {
            "properties": {
              "id": {
                "type": "string"
              },
              "provider": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "state": {
                "properties": {
                  "downloaded": {
                    "type": "string"
                  },
                  "error": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "eta": {
                    "type": "integer"
                  },
                  "progress": {
                    "type": "number"
                  },
                  "speed": {
                    "type": "number"
                  },
                  "status": {
                    "enum": [
                      "PENDING",
                      "RESOLVING",
                      "DOWNLOADING",
                      "UPLOADING",
                      "COMPLETED",
                      "FAILED"
                    ],
                    "type": "string"
                  },
                  "total": {
                    "type": "string"
                  }
                },
                "required": [
                  "progress",
                  "status"
                ],
                "type": [
                  "object",
                  "null"
                ]
              },
              "type": {
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "type",
              "url"
            ],
            "type": [
              "object",
              "null"
            ]
          },
          "fileSize": {
            "type": [
              "integer",
              "null"
            ]
          },
          "fps": {
            "type": [
              "number",
              "null"
            ]
          },
          "hasAudio": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "hasVideo": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "height": {
            "type": [
              "integer",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "isDeleted": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "meta": {
            "properties": {
              "audioStream": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "videoStream": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "type": [
              "object",
              "null"
            ]
          },
          "mimeType": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "orientation": {
            "type": [
              "integer",
              "null"
            ]
          },
          "path": {
            "type": [
              "string",
              "null"
            ]
          },
          "storage": {
            "type": "string"
          },
          "thumbnailUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "enum": [
              "audio",
              "video",
              "image"
            ],
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          },
          "uploaded": {
            "type": "boolean"
          },
          "width": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "uploaded"
        ],
        "type": "object"
      },
      "UploadList": {
        "description": "A page of upload items.",
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/UploadSummary"
            },
            "type": "array"
          },
          "page": {
            "$ref": "#/components/schemas/Page"
          }
        },
        "required": [
          "data",
          "page"
        ],
        "type": "object"
      },
      "UploadSummary": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "fileSize": {
            "type": [
              "integer",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "mimeType": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "enum": [
              "audio",
              "video",
              "image"
            ],
            "type": "string"
          },
          "uploaded": {
            "type": "boolean"
          }
        },
        "required": [
          "createdAt",
          "id",
          "mimeType",
          "name",
          "type",
          "uploaded"
        ],
        "type": "object"
      },
      "UsageAnalytics": {
        "description": "Aggregated usage analytics with time-bucketed data.\nGranularity depends on the period:\n  DAY -\u003e hourly buckets\n  WEEK, MONTH -\u003e daily buckets\n  QUARTER, YEAR -\u003e monthly buckets",
        "properties": {
          "buckets": {
            "description": "Time-bucketed usage (hourly, daily, or monthly depending on period)",
            "items": {
              "description": "A time-bucketed usage entry (hour, day, or month depending on query period)",
              "properties": {
                "credits": {
                  "type": "integer"
                },
                "date": {
                  "format": "date-time",
                  "type": "string"
                },
                "minutes": {
                  "type": "integer"
                },
                "sessions": {
                  "type": "integer"
                }
              },
              "required": [
                "credits",
                "date",
                "minutes",
                "sessions"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "byQuality": {
            "description": "Breakdown by stream quality tier",
            "items": {
              "properties": {
                "credits": {
                  "type": "integer"
                },
                "minutes": {
                  "type": "integer"
                },
                "quality": {
                  "type": "string"
                }
              },
              "required": [
                "credits",
                "minutes",
                "quality"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "sessionCount": {
            "description": "Number of streaming sessions in the requested period",
            "type": "integer"
          },
          "totalCredits": {
            "description": "Total credits spent in the requested period",
            "type": "integer"
          },
          "totalMinutes": {
            "description": "Total minutes in the requested period",
            "type": "integer"
          }
        },
        "required": [
          "buckets",
          "byQuality",
          "sessionCount",
          "totalCredits",
          "totalMinutes"
        ],
        "type": "object"
      },
      "User": {
        "properties": {
          "avatarURL": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "defaultStreamDuration": {
            "description": "Default stream duration in seconds. 0 = never expires, null = system default",
            "type": [
              "integer",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "firstName": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "lastName": {
            "type": [
              "string",
              "null"
            ]
          },
          "locale": {
            "description": "User UI locale preference (BCP-47-like, e.g. \"en-US\"). nil = system default.",
            "type": [
              "string",
              "null"
            ]
          },
          "role": {
            "enum": [
              "admin",
              "user",
              "operator"
            ],
            "type": "string"
          }
        },
        "required": [
          "createdAt",
          "id",
          "role"
        ],
        "type": "object"
      },
      "Workspace": {
        "description": "A workspace you are a member of: its ids, its name, and your role in it.",
        "properties": {
          "active": {
            "description": "True for the workspace THIS request already resolves to, i.e. the default when no workspaceId is passed.",
            "type": "boolean"
          },
          "id": {
            "description": "Workspace id (wksp_…). Send it as X-Workspace-Id or a `workspaceId` argument.",
            "type": "string"
          },
          "identityId": {
            "description": "Organization id; accepted wherever the workspace id is.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "personal": {
            "description": "True for the account's own single-owner workspace, which cannot be deleted while the account exists.",
            "type": "boolean"
          },
          "role": {
            "description": "The authenticated account's role in this workspace. Billing operations require owner or admin.",
            "enum": [
              "owner",
              "admin",
              "member"
            ],
            "type": "string"
          },
          "slug": {
            "type": "string"
          }
        },
        "required": [
          "active",
          "id",
          "name",
          "personal",
          "role",
          "slug"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "apiKey": {
        "description": "A Streamloop API key (prefix `sl_`), sent in the `X-API-Key` header. Create and manage keys in the dashboard. The simplest auth for programmatic / agent clients — no OAuth flow required; the key acts as its owning user.",
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      },
      "bearerAuth": {
        "bearerFormat": "JWT",
        "description": "An OAuth 2.1 bearer access token.",
        "scheme": "bearer",
        "type": "http"
      },
      "oauth2": {
        "description": "OAuth 2.1 authorization-code flow with PKCE.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://auth.streamloop.app/api/auth/oauth2/authorize",
            "scopes": {
              "streamloop:billing": "Read billing/usage and create top-up links",
              "streamloop:destructive": "Delete streams and destinations",
              "streamloop:read": "Read streams, destinations, playlists, and billing status",
              "streamloop:write": "Create and control streams, destinations, and playlists"
            },
            "tokenUrl": "https://auth.streamloop.app/api/auth/oauth2/token"
          }
        },
        "type": "oauth2"
      }
    }
  },
  "info": {
    "contact": {
      "name": "Streamloop",
      "url": "https://streamloop.app"
    },
    "description": "The Streamloop REST API. Authenticate with either an `X-API-Key` header (a Streamloop API key, prefix `sl_` — simplest for programmatic clients) or an OAuth 2.1 bearer access token (obtain one via https://auth.streamloop.app). With an API key, name the workspace in `X-Workspace-Id` (GET /workspaces lists yours). Collections are cursor-paginated (`limit` + `cursor`, returning `{ data, page }`). Errors are RFC 7807 problem documents.",
    "summary": "Programmatic access to Streamloop — create and control 24/7 loop streams, manage media, destinations, playlists, and billing.",
    "title": "Streamloop API",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/batch": {
      "post": {
        "description": "Validates the complete envelope before dispatch, then executes operations sequentially through their normal REST routes. Results preserve input order. An operation failure does not stop later operations, and the batch is not transactional.",
        "operationId": "executeBatch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "items": {
                  "$ref": "#/components/schemas/BatchOperation"
                },
                "maxItems": 20,
                "minItems": 1,
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/BatchResult"
                  },
                  "type": "array"
                }
              }
            },
            "description": "Ordered per-operation results. Individual results can contain non-2xx statuses."
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The batch envelope is invalid; no operations were executed."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Authentication is required."
          }
        },
        "security": [
          {
            "oauth2": []
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Execute up to 20 REST operations.",
        "tags": [
          "meta"
        ]
      }
    },
    "/billing/invoices": {
      "get": {
        "operationId": "listInvoices",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Maximum items to return (1-100, default 20).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Pagination cursor from a previous response's `page.nextCursor`.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceList"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "List invoices",
        "tags": [
          "billing"
        ]
      }
    },
    "/billing/overview": {
      "get": {
        "operationId": "billingOverview",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/BillingOverview"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Get billing overview",
        "tags": [
          "billing"
        ]
      }
    },
    "/billing/top-up/card-link": {
      "post": {
        "description": "Purchase credits by dollar amount. amountCents is the dollar amount in cents (e.g. 500 = $5).\n\nDefault (no savedCardId): returns a checkout URL from the selected payment\nprovider for hosted checkout.\n\nWhen savedCardId is set: the referenced vaulted card is charged off-session on\nthe same provider (no redirect) and checkoutUrl is empty on success. checkoutUrl\nis only populated when the provider requires an interactive step (e.g. a 3DS/SCA\nre-authentication) to complete the charge. savedCardId and saveCard=true are\nmutually exclusive. Requires workspace role owner or admin.",
        "operationId": "topUpUsingCardLink",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TopUpUsingCardLinkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutLink"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:billing"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Create a card top-up link",
        "tags": [
          "billing"
        ]
      }
    },
    "/billing/usage": {
      "get": {
        "operationId": "getUsage",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Aggregation window.",
            "in": "query",
            "name": "period",
            "required": false,
            "schema": {
              "default": "QUARTER",
              "enum": [
                "DAY",
                "WEEK",
                "MONTH",
                "QUARTER",
                "YEAR"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageAnalytics"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Get usage analytics",
        "tags": [
          "billing"
        ]
      }
    },
    "/crypto/currencies": {
      "get": {
        "description": "List all supported cryptocurrencies with live rates.",
        "operationId": "listCryptoCurrencies",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/CryptoCurrency"
                  },
                  "type": "array"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "List crypto currencies",
        "tags": [
          "crypto"
        ]
      }
    },
    "/crypto/deposit-address": {
      "get": {
        "description": "Get (or lazily create) a deposit address for the authenticated user.\nid must be a valid 0xProcessing currency identifier from cryptoCurrencies.",
        "operationId": "getCryptoDepositAddress",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Currency id from GET /crypto/currencies (e.g. a USDT/USDC/BTC/ETH/SOL identifier).",
            "in": "query",
            "name": "currency",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CryptoDepositAddress"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:billing"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Get a crypto deposit address",
        "tags": [
          "crypto"
        ]
      }
    },
    "/destinations": {
      "get": {
        "operationId": "listDestinations",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Maximum items to return (1-100, default 20).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Pagination cursor from a previous response's `page.nextCursor`.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DestinationList"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "List destinations",
        "tags": [
          "destinations"
        ]
      },
      "post": {
        "operationId": "createRtmpDestination",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRtmpDestinationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Destination"
                }
              }
            },
            "description": "Created.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Create an RTMP destination",
        "tags": [
          "destinations"
        ]
      }
    },
    "/me": {
      "get": {
        "operationId": "getMe",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/User"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Get your profile",
        "tags": [
          "account"
        ]
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenapi",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "The OpenAPI document."
          }
        },
        "security": [],
        "summary": "This OpenAPI 3.1 document — unauthenticated.",
        "tags": [
          "meta"
        ]
      }
    },
    "/playlists": {
      "get": {
        "description": "Every stream owns two playlists (video and audio); a scene owns the playlists its sources play. Filter by streamId or sceneId.",
        "operationId": "listPlaylists",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Maximum items to return (1-100, default 20).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Pagination cursor from a previous response's `page.nextCursor`.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only the playlists of this stream (stream_…).",
            "in": "query",
            "name": "streamId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only the playlists of this scene (scn_…).",
            "in": "query",
            "name": "sceneId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaylistList"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "List playlists",
        "tags": [
          "playlists"
        ]
      },
      "post": {
        "description": "Creates an empty playlist owned by a scene, for one of its playlist sources (a stream's own two playlists come with the stream). Fill it with POST /playlists/{id}/operations.",
        "operationId": "createPlaylist",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePlaylistRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaylistSummary"
                }
              }
            },
            "description": "Created.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Create a scene playlist",
        "tags": [
          "playlists"
        ]
      }
    },
    "/playlists/{id}": {
      "get": {
        "description": "Fetches an object given its ID.",
        "operationId": "getPlaylist",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Playlist"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Get a playlist",
        "tags": [
          "playlists"
        ]
      }
    },
    "/playlists/{id}/copy": {
      "post": {
        "description": "Spec copy between two playlists the caller owns. Target must be\nempty. Caller pushes target via stream launch to actually play it.",
        "operationId": "copyPlaylist",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopyPlaylistRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopyPlaylistPayload"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Copy a playlist",
        "tags": [
          "playlists"
        ]
      }
    },
    "/playlists/{id}/operations": {
      "post": {
        "description": "Edits the playlist's draft: operations apply in order, each seeing what the earlier ones made, and a refused one writes nothing. addObjects takes upload ids (obj_…, the id of POST /uploads and GET /uploads) of completed uploads (uploaded true; else OBJECT_NOT_READY). A stream that isn't live plays the draft as it is when it starts; a live stream keeps playing what it started with until POST /playlists/{id}/publish.",
        "operationId": "applyPlaylistOperations",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplyPlaylistOperationsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplyPlaylistOperationsPayload"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Apply playlist operations",
        "tags": [
          "playlists"
        ]
      }
    },
    "/playlists/{id}/publish": {
      "post": {
        "description": "Puts the playlist's draft on its live stream, replacing what it plays without going off air. Only for a stream that is live: a stream that isn't plays its playlists as they are when it starts, so edits made before POST /streams/{id}/start need no publish (here they are 409 NOT_LIVE). expectedDraftVersion is the version you reviewed (the playlist's version). Asynchronous: poll GET /playlists/{id} until publishStatus is IDLE (done) or FAILED. Refusals, by the problem's code: STALE_DRAFT (409; a newer draft, the problem carries currentVersion: re-read and retry), EMPTY_PLAYLIST, BROKEN_ITEM (an item's upload is incomplete or removed; carries objectId), METADATA_PENDING (a video's width and height had not arrived within 40 s; retry), ORIENTATION_CHANGED, RECIPE_MISMATCH, NOT_LIVE (409), NOT_FOUND (404).",
        "operationId": "publishPlaylist",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublishPlaylistRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublishPlaylistPayload"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Publish a playlist",
        "tags": [
          "playlists"
        ]
      }
    },
    "/status": {
      "get": {
        "operationId": "getStatus",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            },
            "description": "Service is operational."
          }
        },
        "security": [],
        "summary": "Service status (liveness/health) — unauthenticated.",
        "tags": [
          "meta"
        ]
      }
    },
    "/streams": {
      "get": {
        "description": "List the streams you own. Supply the ids parameter to fetch a specific set; otherwise the full collection is returned, cursor-paginated.",
        "operationId": "listStreams",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Maximum items to return (1-100, default 20).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Pagination cursor from a previous response's `page.nextCursor`.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter to specific stream IDs (repeatable, or comma-separated). Returns only the streams you own among them, in the usual paginated envelope.",
            "explode": true,
            "in": "query",
            "name": "ids",
            "required": false,
            "schema": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "style": "form"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamList"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "List streams",
        "tags": [
          "streams"
        ]
      },
      "post": {
        "description": "Creates a stream with its two empty playlists (video and audio). Add where it publishes with POST /streams/{id}/destinations and when it runs with POST /streams/{id}/schedule.",
        "operationId": "createStream",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateStreamRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stream"
                }
              }
            },
            "description": "Created.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Create a stream",
        "tags": [
          "streams"
        ]
      }
    },
    "/streams/{id}": {
      "delete": {
        "operationId": "deleteStream",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:destructive"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Delete a stream",
        "tags": [
          "streams"
        ]
      },
      "get": {
        "description": "Fetches an object given its ID.",
        "operationId": "getStream",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Stream"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Get a stream",
        "tags": [
          "streams"
        ]
      },
      "patch": {
        "description": "Changes a stream's settings. Its destinations, schedule and scene have their own routes.",
        "operationId": "updateStream",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateStreamRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stream"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Update a stream",
        "tags": [
          "streams"
        ]
      }
    },
    "/streams/{id}/destinations": {
      "get": {
        "description": "Where the stream publishes, in the order they were added: each destination, whether it is enabled, and its delivery state while the stream runs.",
        "operationId": "listStreamDestinations",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/StreamDestinations"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "List a stream's destinations",
        "tags": [
          "streams"
        ]
      },
      "post": {
        "description": "Adds one of your destinations (GET /destinations) to the stream, enabled; returns the stream's destinations. Up to 5 per stream, one YouTube channel at most; a second destination needs multistream on the workspace (403 MULTISTREAM_NOT_ENABLED). Refused while the stream is live (409 STREAM_LIVE), and for a destination the stream's quality cannot reach (422 DESTINATION_INCOMPATIBLE, with reason).",
        "operationId": "addStreamDestination",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddStreamDestinationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamDestinations"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Add a destination to a stream",
        "tags": [
          "streams"
        ]
      }
    },
    "/streams/{id}/destinations/{destinationId}": {
      "delete": {
        "description": "Takes the destination off the stream (the destination itself stays); returns the stream's remaining destinations. Refused while the stream is live (409 STREAM_LIVE): disable it instead.",
        "operationId": "removeStreamDestination",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "destinationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamDestinations"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Remove a destination from a stream",
        "tags": [
          "streams"
        ]
      },
      "patch": {
        "description": "Stops or resumes sending to one destination without removing it. Disabling works while the stream is live, except for its last enabled destination (409 LAST_DESTINATION); enabling is refused while live (409 STREAM_LIVE).",
        "operationId": "setStreamDestinationEnabled",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "destinationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetStreamDestinationEnabledRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamDestinations"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Enable or disable a stream's destination",
        "tags": [
          "streams"
        ]
      }
    },
    "/streams/{id}/live-stats": {
      "get": {
        "description": "Fetches an object given its ID.",
        "operationId": "getStreamLiveStats",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/StreamLiveStats"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Get live stream stats",
        "tags": [
          "streams"
        ]
      }
    },
    "/streams/{id}/readiness": {
      "get": {
        "description": "What would stop POST /streams/{id}/start, changing nothing: ready, and each blocking issue (code, error, suggestion; destinationId when it is about one destination). It checks that quality and framerate are set; that at least one destination is enabled and not archived, supports the stream's quality, and for YouTube has its broadcast settings (title, made-for-kids) and a connected channel; that the video playlist has items, and that there is an audio playlist when a video in it has no sound; that the playlists' media fits the stream's included storage (else set storageBackend to the large tier with PATCH /streams/{id}); and, for a stream that plays a scene, that the scene is published and valid and the stream is at most 1080p60. It does not check credits or YouTube live eligibility (start does), nor whether uploads have finished processing: a playlist only takes completed uploads, and their metadata (see GET /uploads/{id}) need not have arrived yet.",
        "operationId": "checkStreamReadiness",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StreamReadiness"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Check stream readiness",
        "tags": [
          "streams"
        ]
      }
    },
    "/streams/{id}/scene": {
      "put": {
        "description": "Makes the stream play a scene (its published version; the Scenes API builds and publishes it) instead of its video playlist; sceneId null goes back to the playlist. The scene must be in the stream's workspace (404 NOT_FOUND). Refused while the stream runs (409 STREAM_LIVE): stop it, set the scene, start it.",
        "operationId": "setStreamScene",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetStreamSceneRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stream"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Put a scene on a stream",
        "tags": [
          "streams"
        ]
      }
    },
    "/streams/{id}/schedule": {
      "delete": {
        "description": "Cancel a stream's schedule, including any daily or weekly repeat; the\nstream returns to draft.",
        "operationId": "cancelStreamSchedule",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stream"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Cancel a stream's schedule",
        "tags": [
          "streams"
        ]
      },
      "post": {
        "description": "Sets the window the stream runs in and arms it. Times must be RFC3339 with an explicit UTC offset. repeat=daily re-arms the window +24h and repeat=weekly +7 days (or on the UTC weekdays in days); both require scheduleEndAt and a window shorter than 24h, while a one-off (the default) may be open-ended. days are the UTC weekdays of the start instant, so a 9pm Monday Eastern window repeats on TUESDAY.",
        "operationId": "scheduleStream",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleStreamRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stream"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Schedule a stream",
        "tags": [
          "streams"
        ]
      }
    },
    "/streams/{id}/start": {
      "post": {
        "description": "Starts the stream now. Allowed from draft, scheduled (it starts now instead of at its window), stopped, failed and invalid; any other state is 409 STREAM_ILLEGAL_TRANSITION. It first runs the checks GET /streams/{id}/readiness runs, plus a YouTube live-eligibility check; when one fails the answer is still 200, with the stream in state invalid (GET /streams/{id}/readiness says why; fix it and start again). 422 STREAM_GUARD_FAILED (the problem also carries reason and cause) is a refusal at the moment of starting. The stream plays its playlists as they are when it starts, so edits made while it is not live need no publish. Answers once the start is accepted (state preparing): it is live within about a minute, longer while media is prepared.",
        "operationId": "startStream",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stream"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Start a stream",
        "tags": [
          "streams"
        ]
      }
    },
    "/streams/{id}/stop": {
      "post": {
        "description": "Stop the stream. Works from any running or scheduled state; the stream\nstops publishing and becomes inactive.",
        "operationId": "stopStream",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stream"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Stop a stream",
        "tags": [
          "streams"
        ]
      }
    },
    "/uploads": {
      "get": {
        "operationId": "listUploads",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Maximum items to return (1-100, default 20).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Pagination cursor from a previous response's `page.nextCursor`.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadList"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "List uploads",
        "tags": [
          "uploads"
        ]
      },
      "post": {
        "description": "Creates an upload record for a direct single-PUT transfer. Its id (obj_…) is the media id everywhere: what POST /playlists/{id}/operations takes in addObjects.objectIds and what a playlist's items (objectID) and liveItems (objectId) name. name needs a file extension; mimeType must suit type (video, audio or image) and is the Content-Type the PUT must send. A file may be at most 15 GB, but one PUT carries at most 5 GB, so import a bigger file with POST /uploads/from-link instead; a fileSize given here is checked now (422 FILE_TOO_LARGE), and the stored size is checked again on complete. A name without an extension or a mimeType that doesn't suit type is 422 INVALID_INPUT. Next: POST /uploads/{id}/upload-url, PUT the bytes to that URL, then POST /uploads/{id}/complete.",
        "operationId": "createUpload",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUploadRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload"
                }
              }
            },
            "description": "Created.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Create an upload",
        "tags": [
          "uploads"
        ]
      }
    },
    "/uploads/from-link": {
      "post": {
        "description": "Imports media from a link (YouTube, a cloud drive, a direct file URL…): one upload per selection, downloaded in the background; answers 202 with the new uploads. Each selection names an assetId and a qualityId from discovery, which this REST API does not offer: ask GraphQL (POST https://api.streamloop.app/graphql, the same X-API-Key) with `query { externalLinkContents(url: \"\u003clink\u003e\") { provider items { id name durationSeconds qualities { id label height } } } }` — an item's id is the assetId, a quality's id the qualityId — or use the MCP tool discover_external_media. Then poll GET /uploads/{id}: externalSource.state.status goes PENDING, RESOLVING, DOWNLOADING, UPLOADING, then COMPLETED (uploaded true) or FAILED (state.error says why). The Location header is the first upload's; the body has every id.",
        "operationId": "createUploadFromLink",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUploadFromLinkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/Upload"
                  },
                  "type": "array"
                }
              }
            },
            "description": "Accepted — the work goes on in the background; the body has its ids and Location is where to poll for the result.",
            "headers": {
              "Location": {
                "description": "Where to poll for the result: GET /uploads/{id} (the first item's, when the answer is a list; the body has every id).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Import uploads from a link",
        "tags": [
          "uploads"
        ]
      }
    },
    "/uploads/remove": {
      "post": {
        "description": "Removes up to 100 uploads from the media library, as DELETE /uploads/{id} does for one (an upload that never finished is left in place here: UPLOAD_INCOMPLETE; DELETE it). The call succeeds as a whole: removedIds lists what is gone (including ids that already were), refused lists each id left in place with its reason (NOT_FOUND, IN_USE, UNSUPPORTED_TYPE, UPLOAD_INCOMPLETE). When one id failed for a passing reason the whole call is 503 UNAVAILABLE naming it: what was removed stays removed, so send the call again. More than 100 ids is a 422.",
        "operationId": "removeUploads",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RemoveUploadsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RemoveUploadsResult"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:destructive"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Remove uploads",
        "tags": [
          "uploads"
        ]
      }
    },
    "/uploads/{id}": {
      "delete": {
        "description": "Removes the upload from the media library for good: its stored bytes and every file derived from it are deleted, and it no longer lists. An upload that never finished (no complete after the PUT, an import that failed) is dropped too: nothing was stored. Refused with 409 IN_USE while a playlist or a recent stream still uses it (remove it from those playlists first), 404 NOT_FOUND, 422 UNSUPPORTED_TYPE for an image. Removing an already-removed upload succeeds.",
        "operationId": "removeUpload",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:destructive"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Remove an upload",
        "tags": [
          "uploads"
        ]
      },
      "get": {
        "description": "One upload (obj_…). There is no separate processing state: uploaded turns true on POST /uploads/{id}/complete (or when an import finishes), and the media's facts (duration, width, height, fps, hasVideo, hasAudio) arrive a few seconds to about half a minute later; they are null until then. A playlist takes the upload as soon as uploaded is true; publishing a live playlist waits up to 40 s for a video's width and height (else 422 METADATA_PENDING, retry). An import shows its progress in externalSource.state; externalSource is null for a direct upload.",
        "operationId": "getUpload",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Upload"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Get an upload",
        "tags": [
          "uploads"
        ]
      }
    },
    "/uploads/{id}/complete": {
      "post": {
        "description": "Call after the PUT to the upload URL succeeded. Checks the stored file's size against the cap (over it: 422 FILE_TOO_LARGE, and the stored file is deleted), sets uploaded true and starts reading the media's facts in the background (see GET /uploads/{id}). The upload can go into a playlist at once. Completing again is harmless; completing before the PUT finished is refused (nothing is stored yet).",
        "operationId": "markUploadComplete",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Mark an upload complete",
        "tags": [
          "uploads"
        ]
      }
    },
    "/uploads/{id}/upload-url": {
      "post": {
        "description": "Answers a JSON string: a presigned storage URL, valid for 11 hours. Send the whole file to it in one HTTP PUT, the bytes as the body, with Content-Type exactly the upload's mimeType (it is part of the signature: another value is refused by storage with 403) and no Streamloop credentials. Storage answers 200 with no body; then POST /uploads/{id}/complete. Ask again for a fresh URL after it expires. The answer is never null: an upload already completed is 409 UPLOAD_ALREADY_COMPLETED, and a removed one 422 UPLOAD_REMOVED.",
        "operationId": "generateUploadUrl",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Resource identifier.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Optional client-generated key. A repeated request with the same key, method and path (by the same caller in the same workspace) replays the original response, with `Idempotency-Replayed: true`, for 24 hours instead of running again — safe retries. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED (nothing runs): use a new key for each new request. A 5xx answer is not remembered (a retry runs).",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Conflicts with the resource's current state, e.g. STREAM_LIVE or IN_USE."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "Generate a presigned upload URL",
        "tags": [
          "uploads"
        ]
      }
    },
    "/workspaces": {
      "get": {
        "description": "Every workspace you are a member of, with your role in each. Pass one's id as X-Workspace-Id: an API key carries no workspace, so every other route needs it.",
        "operationId": "listWorkspaces",
        "parameters": [
          {
            "description": "Workspace this request operates in — the workspace id (`wksp_…`) or the organization id, from GET /workspaces. Required with an API key, which carries no workspace (400 `WORKSPACE_REQUIRED` without it). With an OAuth token it defaults to the workspace the token was issued for. Responds 403 `WORKSPACE_FORBIDDEN` when the caller is not a current member, rather than falling back to another workspace.",
            "in": "header",
            "name": "X-Workspace-Id",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/Workspace"
                  },
                  "type": "array"
                }
              }
            },
            "description": "Successful response.",
            "headers": {
              "RateLimit": {
                "description": "The same three as one structured field: limit=, remaining=, reset= (IETF RateLimit header fields draft).",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Policy": {
                "description": "The quota and its window in seconds: 600;w=60.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests remaining in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No workspace selected: send X-Workspace-Id (WORKSPACE_REQUIRED)."
          },
          "401": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Missing or invalid access token."
          },
          "403": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The token lacks the required scope or access to the resource."
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The resource does not exist or is not visible to the caller."
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The request is invalid, or refused for the resource as it is (the code says why)."
          },
          "429": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Rate limit exceeded. Retry after the indicated delay.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unexpected failure (UPSTREAM_ERROR)."
          }
        },
        "security": [
          {
            "oauth2": [
              "streamloop:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "summary": "List your workspaces",
        "tags": [
          "account"
        ]
      }
    }
  },
  "security": [
    {
      "oauth2": []
    },
    {
      "bearerAuth": []
    },
    {
      "apiKey": []
    }
  ],
  "servers": [
    {
      "description": "Production",
      "url": "https://api.streamloop.app/v1"
    }
  ],
  "tags": [
    {
      "description": "The authenticated user's account and workspaces.",
      "name": "account"
    },
    {
      "description": "Credits, usage analytics, invoices, and top-ups.",
      "name": "billing"
    },
    {
      "description": "Crypto deposit options for topping up credits.",
      "name": "crypto"
    },
    {
      "description": "Manage streaming destinations (custom RTMP).",
      "name": "destinations"
    },
    {
      "description": "Service metadata, discovery documents, and batch execution.",
      "name": "meta"
    },
    {
      "description": "Stream and scene playlists: list, create, edit and publish.",
      "name": "playlists"
    },
    {
      "description": "Create, control, schedule, and monitor 24/7 streams: their destinations and scene.",
      "name": "streams"
    },
    {
      "description": "Upload and manage source media (video/audio).",
      "name": "uploads"
    }
  ]
}
