{
  "openapi": "3.0.3",
  "info": {
    "title": "TRaX Public API",
    "version": "1.3.0",
    "description": "The versioned public developer API for TRaX. Authenticate with a user-scoped API key: `Authorization: Bearer sk_live_...` (or the `X-API-Key` alias). Every response carries an `X-Request-Id`. Errors share one envelope: `{ \"error\": { \"code\", \"message\", \"requestId\" } }`. List endpoints are cursor-paginated: `{ \"data\": [ ... ], \"nextCursor\": \"...\" }`. Phases 1-3 are LIVE: reads + gated go-live (Phase 1), studio/source/destination CRUD + connections (Phase 2), and chat + media library (Phase 3). Mutating endpoints are gated behind PUBLIC_API_WRITE_ENABLED and return 503 write_disabled while off. See trax-dev/docs/public-api-platform-design.md."
  },
  "servers": [
    { "url": "/", "description": "relative to the gateway host (api-dev.traxstreaming.live)" }
  ],
  "tags": [
    { "name": "meta", "description": "Health + spec (unauthenticated)" },
    { "name": "studios", "description": "Studios, sources, destinations, stream status" },
    { "name": "stream", "description": "Go-live / go-offline lifecycle" },
    { "name": "chat", "description": "Unified live-chat messages" },
    { "name": "connections", "description": "Linked platform accounts" },
    { "name": "media", "description": "Media library assets + uploads" }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sk_live",
        "description": "A user-scoped API key minted from the account 'Developer / API Keys' screen. Also accepted via the `X-API-Key` header."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "additionalProperties": false,
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "additionalProperties": false,
            "required": ["code", "message", "requestId"],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code.",
                "enum": [
                  "invalid_key",
                  "insufficient_scope",
                  "not_found",
                  "invalid_request",
                  "rate_limited",
                  "write_disabled",
                  "unavailable",
                  "bad_gateway",
                  "internal"
                ]
              },
              "message": { "type": "string" },
              "requestId": { "type": "string" },
              "requiredScope": {
                "type": "string",
                "description": "Present only on insufficient_scope: the scope the key must hold."
              }
            }
          }
        }
      },
      "Health": {
        "type": "object",
        "additionalProperties": false,
        "required": ["status"],
        "properties": {
          "status": { "type": "string", "example": "ok" },
          "writeEnabled": { "type": "boolean", "description": "Whether mutating (write) endpoints are currently enabled." }
        }
      },
      "Ok": {
        "type": "object",
        "additionalProperties": false,
        "required": ["ok"],
        "properties": { "ok": { "type": "boolean" } }
      },
      "Studio": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "name", "role", "ownerSub"],
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "description": { "type": "string" },
          "role": { "type": "string", "description": "owner | VIEW | EDIT | ADMIN" },
          "ownerSub": { "type": "string" },
          "createdAt": { "type": "string" },
          "lastOpenedAt": { "type": "string" }
        }
      },
      "Source": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "studioId", "name", "type", "active"],
        "properties": {
          "id": { "type": "string" },
          "studioId": { "type": "string" },
          "name": { "type": "string" },
          "type": { "type": "string" },
          "active": { "type": "boolean" },
          "status": { "type": "string" },
          "createdAt": { "type": "string" }
        }
      },
      "Destination": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "studioId", "name", "platform", "enabled", "vertical"],
        "properties": {
          "id": { "type": "string" },
          "studioId": { "type": "string" },
          "name": { "type": "string" },
          "platform": { "type": "string" },
          "enabled": { "type": "boolean" },
          "status": { "type": "string" },
          "vertical": { "type": "boolean" }
        }
      },
      "StreamStatus": {
        "type": "object",
        "additionalProperties": false,
        "required": ["live"],
        "properties": {
          "live": { "type": "boolean" },
          "encoderStreamId": { "type": "string" },
          "liveStartedAt": { "type": "string" },
          "broadcastStartedAt": { "type": "string" },
          "mode": { "type": "string", "description": "cloud | local" }
        }
      },
      "GoLiveResult": {
        "type": "object",
        "additionalProperties": false,
        "required": ["encoderStreamId", "destinationIds"],
        "properties": {
          "encoderStreamId": { "type": "string" },
          "destinationIds": { "type": "array", "items": { "type": "string" } }
        }
      },
      "GoOfflineResult": {
        "type": "object",
        "additionalProperties": false,
        "required": ["ok"],
        "properties": { "ok": { "type": "boolean" } }
      },
      "Connection": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "platform", "displayName", "status", "connectionType"],
        "properties": {
          "id": { "type": "string" },
          "platform": { "type": "string" },
          "displayName": { "type": "string" },
          "externalUserId": { "type": "string" },
          "avatarUrl": { "type": "string" },
          "status": { "type": "string", "description": "active | needs_reauth | expired | revoked" },
          "connectionType": { "type": "string", "description": "oauth | manual" },
          "connectedAt": { "type": "string" },
          "updatedAt": { "type": "string" },
          "expiresAt": { "type": "string" },
          "grantedScopes": { "type": "array", "items": { "type": "string" } }
        }
      },
      "ChatMessage": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "platform", "authorDisplayName", "text"],
        "properties": {
          "id": { "type": "string" },
          "platform": { "type": "string" },
          "authorDisplayName": { "type": "string" },
          "authorId": { "type": "string" },
          "text": { "type": "string" },
          "timestamp": { "type": "string" }
        }
      },
      "ChatSendResult": {
        "type": "object",
        "additionalProperties": false,
        "required": ["ok"],
        "properties": {
          "ok": { "type": "boolean" },
          "messageId": { "type": "string" }
        }
      },
      "MediaAsset": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "filename", "kind", "byteSize", "status"],
        "properties": {
          "id": { "type": "string" },
          "filename": { "type": "string" },
          "kind": { "type": "string", "description": "video | image | audio" },
          "contentType": { "type": "string" },
          "byteSize": { "type": "integer", "format": "int64" },
          "status": { "type": "string", "description": "UPLOADING | READY | FAILED" },
          "folder": { "type": "string" },
          "createdAt": { "type": "string" }
        }
      },
      "MediaUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": ["assetId", "uploadUrl", "objectKey", "kind"],
        "properties": {
          "assetId": { "type": "string" },
          "uploadUrl": { "type": "string", "description": "A short-lived presigned PUT URL to upload the bytes to." },
          "objectKey": { "type": "string" },
          "kind": { "type": "string" }
        }
      },
      "StudioList": {
        "type": "object",
        "additionalProperties": false,
        "required": ["data"],
        "properties": {
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/Studio" } },
          "nextCursor": { "type": "string" }
        }
      },
      "SourceList": {
        "type": "object",
        "additionalProperties": false,
        "required": ["data"],
        "properties": {
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/Source" } },
          "nextCursor": { "type": "string" }
        }
      },
      "DestinationList": {
        "type": "object",
        "additionalProperties": false,
        "required": ["data"],
        "properties": {
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/Destination" } },
          "nextCursor": { "type": "string" }
        }
      },
      "ConnectionList": {
        "type": "object",
        "additionalProperties": false,
        "required": ["data"],
        "properties": {
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/Connection" } },
          "nextCursor": { "type": "string" }
        }
      },
      "ChatMessageList": {
        "type": "object",
        "additionalProperties": false,
        "required": ["data"],
        "properties": {
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/ChatMessage" } },
          "nextCursor": { "type": "string" }
        }
      },
      "MediaAssetList": {
        "type": "object",
        "additionalProperties": false,
        "required": ["data"],
        "properties": {
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/MediaAsset" } },
          "nextCursor": { "type": "string" }
        }
      },
      "CreateStudioRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name"],
        "properties": { "name": { "type": "string" } }
      },
      "UpdateStudioRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": { "type": "string" },
          "autoGoLive": { "type": "boolean" },
          "autoGoOfflineOnDrop": { "type": "boolean" }
        }
      },
      "CreateSourceRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "type"],
        "properties": {
          "name": { "type": "string" },
          "type": { "type": "string", "description": "webcam | rtmp | srt | webrtc-input | media | ..." },
          "url": { "type": "string" },
          "active": { "type": "boolean" }
        }
      },
      "UpdateSourceRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": { "type": "string" },
          "active": { "type": "boolean" },
          "url": { "type": "string" }
        }
      },
      "CreateDestinationRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "platform"],
        "properties": {
          "name": { "type": "string" },
          "platform": { "type": "string" },
          "connectionId": { "type": "string", "description": "Bind to a linked account; mutually exclusive with rtmpUrl+streamKey." },
          "rtmpUrl": { "type": "string" },
          "streamKey": { "type": "string", "description": "Write-only; never returned on any read." },
          "enabled": { "type": "boolean" },
          "vertical": { "type": "boolean" }
        }
      },
      "UpdateDestinationRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": { "type": "string" },
          "platform": { "type": "string" },
          "rtmpUrl": { "type": "string" },
          "streamKey": { "type": "string", "description": "Write-only; never returned on any read." },
          "enabled": { "type": "boolean" },
          "vertical": { "type": "boolean" }
        }
      },
      "SendChatMessageRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["text"],
        "properties": {
          "text": { "type": "string" },
          "platforms": { "type": "array", "items": { "type": "string" }, "description": "Subset to fan out to; empty = every enabled platform." }
        }
      },
      "CreateMediaUploadRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["filename", "contentType", "byteSize"],
        "properties": {
          "filename": { "type": "string" },
          "contentType": { "type": "string" },
          "byteSize": { "type": "integer", "format": "int64" },
          "folder": { "type": "string" }
        }
      }
    },
    "parameters": {
      "StudioId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "type": "string" },
        "description": "Studio id."
      },
      "SourceId": {
        "name": "sourceId",
        "in": "path",
        "required": true,
        "schema": { "type": "string" },
        "description": "Source id."
      },
      "DestId": {
        "name": "destId",
        "in": "path",
        "required": true,
        "schema": { "type": "string" },
        "description": "Destination id."
      },
      "ConnectionId": {
        "name": "connectionId",
        "in": "path",
        "required": true,
        "schema": { "type": "string" },
        "description": "Connection id."
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "schema": { "type": "string" },
        "description": "Opaque pagination cursor from a prior response's nextCursor."
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 },
        "description": "Max items per page (default 50, max 200)."
      }
    },
    "responses": {
      "Error": {
        "description": "Error envelope.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    }
  },
  "security": [ { "ApiKeyBearer": [] } ],
  "paths": {
    "/v1/health": {
      "get": {
        "tags": ["meta"],
        "operationId": "getHealth",
        "summary": "Liveness probe (unauthenticated).",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is up.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Health" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/openapi.json": {
      "get": {
        "tags": ["meta"],
        "operationId": "getOpenapi",
        "summary": "This OpenAPI 3.0 document (unauthenticated).",
        "security": [],
        "responses": {
          "200": {
            "description": "The OpenAPI spec.",
            "content": { "application/json": { "schema": { "type": "object" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios": {
      "get": {
        "tags": ["studios"],
        "operationId": "listStudios",
        "summary": "List the caller's studios.",
        "description": "Requires scope studios:read.",
        "parameters": [
          { "$ref": "#/components/parameters/Cursor" },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": {
          "200": {
            "description": "A page of studios.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StudioList" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      },
      "post": {
        "tags": ["studios"],
        "operationId": "createStudio",
        "summary": "Create a studio.",
        "description": "Requires scope studios:write. Gated behind PUBLIC_API_WRITE_ENABLED.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateStudioRequest" } } }
        },
        "responses": {
          "201": {
            "description": "The created studio.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Studio" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios/{id}": {
      "get": {
        "tags": ["studios"],
        "operationId": "getStudio",
        "summary": "Get one studio.",
        "description": "Requires scope studios:read.",
        "parameters": [ { "$ref": "#/components/parameters/StudioId" } ],
        "responses": {
          "200": {
            "description": "The studio.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Studio" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      },
      "patch": {
        "tags": ["studios"],
        "operationId": "updateStudio",
        "summary": "Update a studio (name / auto-go-live settings).",
        "description": "Requires scope studios:write. Gated behind PUBLIC_API_WRITE_ENABLED. There is no studio delete on the public API.",
        "parameters": [ { "$ref": "#/components/parameters/StudioId" } ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateStudioRequest" } } }
        },
        "responses": {
          "200": {
            "description": "The updated studio.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Studio" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios/{id}/sources": {
      "get": {
        "tags": ["studios"],
        "operationId": "listSources",
        "summary": "List a studio's sources.",
        "description": "Requires scope sources:read.",
        "parameters": [
          { "$ref": "#/components/parameters/StudioId" },
          { "$ref": "#/components/parameters/Cursor" },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": {
          "200": {
            "description": "A page of sources.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SourceList" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      },
      "post": {
        "tags": ["studios"],
        "operationId": "createSource",
        "summary": "Add a source to a studio.",
        "description": "Requires scope sources:write. Gated behind PUBLIC_API_WRITE_ENABLED.",
        "parameters": [ { "$ref": "#/components/parameters/StudioId" } ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSourceRequest" } } }
        },
        "responses": {
          "201": {
            "description": "The created source.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Source" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios/{id}/sources/{sourceId}": {
      "patch": {
        "tags": ["studios"],
        "operationId": "updateSource",
        "summary": "Update a source.",
        "description": "Requires scope sources:write. Gated behind PUBLIC_API_WRITE_ENABLED.",
        "parameters": [
          { "$ref": "#/components/parameters/StudioId" },
          { "$ref": "#/components/parameters/SourceId" }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateSourceRequest" } } }
        },
        "responses": {
          "200": {
            "description": "The updated source.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Source" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      },
      "delete": {
        "tags": ["studios"],
        "operationId": "deleteSource",
        "summary": "Remove a source.",
        "description": "Requires scope sources:write. Gated behind PUBLIC_API_WRITE_ENABLED.",
        "parameters": [
          { "$ref": "#/components/parameters/StudioId" },
          { "$ref": "#/components/parameters/SourceId" }
        ],
        "responses": {
          "200": {
            "description": "The source was removed.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios/{id}/destinations": {
      "get": {
        "tags": ["studios"],
        "operationId": "listDestinations",
        "summary": "List a studio's destinations.",
        "description": "Requires scope destinations:read.",
        "parameters": [
          { "$ref": "#/components/parameters/StudioId" },
          { "$ref": "#/components/parameters/Cursor" },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": {
          "200": {
            "description": "A page of destinations.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DestinationList" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      },
      "post": {
        "tags": ["studios"],
        "operationId": "createDestination",
        "summary": "Add a destination to a studio.",
        "description": "Requires scope destinations:write. Gated behind PUBLIC_API_WRITE_ENABLED. The stream key is write-only and never returned.",
        "parameters": [ { "$ref": "#/components/parameters/StudioId" } ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDestinationRequest" } } }
        },
        "responses": {
          "201": {
            "description": "The created destination.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Destination" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios/{id}/destinations/{destId}": {
      "patch": {
        "tags": ["studios"],
        "operationId": "updateDestination",
        "summary": "Update a destination.",
        "description": "Requires scope destinations:write. Gated behind PUBLIC_API_WRITE_ENABLED.",
        "parameters": [
          { "$ref": "#/components/parameters/StudioId" },
          { "$ref": "#/components/parameters/DestId" }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateDestinationRequest" } } }
        },
        "responses": {
          "200": {
            "description": "The updated destination.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Destination" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      },
      "delete": {
        "tags": ["studios"],
        "operationId": "deleteDestination",
        "summary": "Remove a destination.",
        "description": "Requires scope destinations:write. Gated behind PUBLIC_API_WRITE_ENABLED.",
        "parameters": [
          { "$ref": "#/components/parameters/StudioId" },
          { "$ref": "#/components/parameters/DestId" }
        ],
        "responses": {
          "200": {
            "description": "The destination was removed.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios/{id}/stream-status": {
      "get": {
        "tags": ["studios"],
        "operationId": "getStreamStatus",
        "summary": "Get a studio's live/offline stream status.",
        "description": "Requires scope stream:read.",
        "parameters": [ { "$ref": "#/components/parameters/StudioId" } ],
        "responses": {
          "200": {
            "description": "The stream status.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StreamStatus" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios/{id}/go-live": {
      "post": {
        "tags": ["stream"],
        "operationId": "goLive",
        "summary": "Take a studio live.",
        "description": "Requires scope stream:golive. Gated behind PUBLIC_API_WRITE_ENABLED; returns 503 write_disabled while off.",
        "parameters": [ { "$ref": "#/components/parameters/StudioId" } ],
        "responses": {
          "200": {
            "description": "The studio is going live.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GoLiveResult" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios/{id}/go-offline": {
      "post": {
        "tags": ["stream"],
        "operationId": "goOffline",
        "summary": "Take a studio offline.",
        "description": "Requires scope stream:golive. Gated behind PUBLIC_API_WRITE_ENABLED; returns 503 write_disabled while off.",
        "parameters": [ { "$ref": "#/components/parameters/StudioId" } ],
        "responses": {
          "200": {
            "description": "The studio is going offline.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GoOfflineResult" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/studios/{id}/chat/messages": {
      "get": {
        "tags": ["chat"],
        "operationId": "listChatMessages",
        "summary": "List a studio's recent unified-chat messages.",
        "description": "Requires scope chat:read. Returns the most recent messages (bounded by limit); no cursor.",
        "parameters": [
          { "$ref": "#/components/parameters/StudioId" },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": {
          "200": {
            "description": "Recent chat messages.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatMessageList" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      },
      "post": {
        "tags": ["chat"],
        "operationId": "sendChatMessage",
        "summary": "Send a message into the studio's unified chat.",
        "description": "Requires scope chat:send. Gated behind PUBLIC_API_WRITE_ENABLED. Fans out to the enabled platforms.",
        "parameters": [ { "$ref": "#/components/parameters/StudioId" } ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendChatMessageRequest" } } }
        },
        "responses": {
          "201": {
            "description": "The message was accepted for fan-out.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatSendResult" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/connections": {
      "get": {
        "tags": ["connections"],
        "operationId": "listConnections",
        "summary": "List the caller's linked platform accounts.",
        "description": "Requires scope connections:read. Metadata only — never tokens or stream keys.",
        "parameters": [
          { "$ref": "#/components/parameters/Cursor" },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": {
          "200": {
            "description": "A page of connections.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConnectionList" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/connections/{connectionId}": {
      "delete": {
        "tags": ["connections"],
        "operationId": "deleteConnection",
        "summary": "Unlink a connection.",
        "description": "Requires scope connections:write. Gated behind PUBLIC_API_WRITE_ENABLED.",
        "parameters": [ { "$ref": "#/components/parameters/ConnectionId" } ],
        "responses": {
          "200": {
            "description": "The connection was unlinked.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Ok" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/media": {
      "get": {
        "tags": ["media"],
        "operationId": "listMedia",
        "summary": "List the caller's media-library assets.",
        "description": "Requires scope media:read.",
        "parameters": [
          { "$ref": "#/components/parameters/Cursor" },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": {
          "200": {
            "description": "A page of media assets.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaAssetList" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      },
      "post": {
        "tags": ["media"],
        "operationId": "createMediaUpload",
        "summary": "Initiate a media upload (returns a presigned PUT).",
        "description": "Requires scope media:write. Gated behind PUBLIC_API_WRITE_ENABLED. Reserves an asset row and returns a short-lived presigned PUT URL; upload the bytes to it, then the asset transitions to READY once processed.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateMediaUploadRequest" } } }
        },
        "responses": {
          "201": {
            "description": "An upload was initiated.",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaUpload" } } }
          },
          "default": { "$ref": "#/components/responses/Error" }
        }
      }
    }
  }
}
