{
  "openapi": "3.1.0",
  "info": {
    "title": "PostRoutine API",
    "version": "1.5.7",
    "description": "The PostRoutine API lets you schedule and manage social media posts across all major platforms programmatically. Use it to build custom integrations, automate your publishing workflows, or connect PostRoutine to your own tools.\n\n## Base URL\n\n```\nhttps://qnadvdhrowsqgqimlues.supabase.co/functions/v1/api/v1\n```\n\n## Authentication\n\nAuthenticate every request with an API key in the `Authorization` header:\n\n```\nAuthorization: Bearer pr_xxxxxxxxxxxxxxxx\n```\n\nYou can generate and manage API keys from your [dashboard](https://postroutine.io/dashboard/api-keys). Keys start with `pr_` and should be kept secret — never expose them in client-side code or public repositories.\n\n## Rate Limits\n\n- **100 requests per minute** per API key\n- Standard rate limit headers (`RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`) are included in every response\n- If you exceed the limit, you'll receive a `429` response — wait and retry after the reset window\n\n## Response Format\n\nAll successful responses include a `data` field:\n\n```json\n{\n  \"data\": { ... }\n}\n```\n\nPaginated endpoints also include `page` and `limit`:\n\n```json\n{\n  \"data\": [ ... ],\n  \"page\": 1,\n  \"limit\": 50\n}\n```\n\n## Errors\n\nAll errors return an `error` field:\n\n```json\n{\n  \"error\": \"Post not found\"\n}\n```\n\n## Timestamps & Timezones\n\nAll timestamps are in **UTC** using ISO 8601 format (`2026-03-15T14:00:00.000Z`). The API does not accept or return timezone offsets — convert to UTC before sending.\n\nCommon error codes:\n\n| HTTP Status | Meaning |\n|---|---|\n| 400 | Invalid or missing parameters |\n| 401 | Missing, invalid, or expired API key |\n| 403 | Valid API key but insufficient permissions |\n| 404 | Resource doesn't exist or you don't have access |\n| 429 | Too many requests — slow down |\n| 500 | Something went wrong on our end |",
    "contact": {
      "name": "PostRoutine Support",
      "url": "https://postroutine.io",
      "email": "support@postroutine.io"
    }
  },
  "servers": [
    {
      "url": "https://qnadvdhrowsqgqimlues.supabase.co/functions/v1/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key (starts with `pr_`)"
      }
    },
    "parameters": {
      "Id": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "format": "uuid" }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Unique key used to safely replay an ads write.",
        "schema": { "type": "string", "maxLength": 255 }
      }
    },
    "responses": {
      "Forbidden": {
        "description": "The API key lacks the required scope or the caller lacks the required workspace role.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {
                  "type": "object",
                  "properties": {
                    "code": { "type": "string", "enum": ["insufficient_scope", "insufficient_role"] },
                    "message": { "type": "string" }
                  },
                  "required": ["code", "message"]
                }
              },
              "required": ["error"]
            }
          }
        }
      }
    },
    "schemas": {
      "WorkspaceRole": {
        "type": "string",
        "enum": ["viewer", "member", "admin", "billing_manager", "owner"]
      },
      "IssueApiKeyRequest": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string" },
          "permission": { "type": "string", "enum": ["read", "read-write"], "default": "read-write" },
          "scope": { "type": "string", "enum": ["full", "brands"], "default": "full" },
          "brand_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } },
          "scopes": {
            "type": "array",
            "items": { "type": "string" },
            "example": ["posts:read", "posts:write", "webhooks:read"]
          },
          "expires_at": { "type": ["string", "null"], "format": "date-time" }
        }
      },
      "WebhookRequest": {
        "type": "object",
        "required": ["url", "events"],
        "properties": {
          "name": { "type": "string" },
          "url": { "type": "string", "format": "uri" },
          "events": { "type": "array", "minItems": 1, "items": { "type": "string" } },
          "is_active": { "type": "boolean", "default": true },
          "custom_headers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": { "key": { "type": "string" }, "value": { "type": "string", "writeOnly": true } },
              "required": ["key", "value"]
            }
          }
        }
      },
      "Post": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "content": { "type": "string" },
          "caption": { "type": "string", "description": "Alias for content" },
          "title": { "type": "string", "nullable": true },
          "status": { "type": "string", "enum": ["draft", "scheduled", "processing", "published", "failed"] },
          "is_draft": { "type": "boolean" },
          "scheduled_at": { "type": "string", "format": "date-time", "nullable": true },
          "published_at": { "type": "string", "format": "date-time", "nullable": true },
          "brand_id": { "type": "string", "format": "uuid", "nullable": true },
          "media_urls": { "type": "array", "items": { "type": "string" } },
          "platform_configurations": { "type": "object" },
          "social_accounts": { "type": "array", "items": { "type": "string", "format": "uuid" } },
          "post_targets": { "type": "array", "items": { "$ref": "#/components/schemas/PostTarget" } },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "PostTarget": {
        "type": "object",
        "properties": {
          "post_id": { "type": "string", "format": "uuid" },
          "social_account_id": { "type": "string", "format": "uuid" },
          "status": { "type": "string", "enum": ["pending", "published", "failed"] },
          "platform_post_id": { "type": "string", "nullable": true },
          "published_at": { "type": "string", "format": "date-time", "nullable": true },
          "error_message": { "type": "string", "nullable": true }
        }
      },
      "SocialAccount": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "platform": { "type": "string", "enum": ["instagram", "facebook", "x", "linkedin", "youtube", "tiktok", "threads", "pinterest", "bluesky", "reddit", "snapchat", "telegram", "whatsapp", "discord", "googlebusiness"] },
          "platform_display_name": { "type": "string" },
          "platform_username": { "type": "string" },
          "platform_avatar_url": { "type": "string", "nullable": true },
          "brand_id": { "type": "string", "format": "uuid", "nullable": true },
          "is_active": { "type": "boolean" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "Brand": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "logo_url": { "type": "string", "nullable": true },
          "target_audience": { "type": "string", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "MediaAsset": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "kind": { "type": "string" },
          "mime": { "type": "string" },
          "original_name": { "type": "string", "nullable": true },
          "size_bytes": { "type": "integer" },
          "url": { "type": "string", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "Queue": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "timezone": { "type": "string" },
          "is_active": { "type": "boolean" },
          "is_default": { "type": "boolean" },
          "brand_id": { "type": "string", "format": "uuid", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "QueueSlot": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "day_of_week": { "type": "integer", "minimum": 0, "maximum": 6 },
          "time": { "type": "string", "example": "09:00:00" },
          "is_active": { "type": "boolean" },
          "brand_id": { "type": "string", "format": "uuid", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "CreatePostRequest": {
        "type": "object",
        "required": ["caption", "social_accounts"],
        "properties": {
          "caption": { "type": "string", "description": "Post content/caption" },
          "title": { "type": "string", "description": "Optional title" },
          "social_accounts": { "type": "array", "items": { "type": "string", "format": "uuid" }, "description": "Social account IDs to post to" },
          "scheduled_at": { "type": "string", "format": "date-time", "description": "UTC schedule time. Omit for draft." },
          "is_draft": { "type": "boolean", "default": false },
          "publish_now": { "type": "boolean", "default": false, "description": "Publish immediately instead of scheduling" },
          "use_queue": { "type": "boolean", "default": false, "description": "Auto-schedule to the next free queue slot" },
          "queue_id": { "type": "string", "format": "uuid", "description": "Optional queue ID when use_queue is true" },
          "brand_id": { "type": "string", "format": "uuid" },
          "media": { "type": "array", "items": { "type": "string" }, "description": "Array of media URLs (alias: media_urls)" },
          "media_urls": { "type": "array", "items": { "type": "string" }, "description": "Array of media URLs" },
          "processing_enabled": { "type": "boolean", "default": true, "description": "Enable video compression before publish" },
          "platform_configurations": { "type": "object", "description": "Platform-specific settings" }
        }
      },
      "UpdatePostRequest": {
        "type": "object",
        "properties": {
          "caption": { "type": "string" },
          "title": { "type": "string" },
          "scheduled_at": { "type": "string", "format": "date-time" },
          "is_draft": { "type": "boolean" },
          "status": { "type": "string" },
          "brand_id": { "type": "string", "format": "uuid" },
          "media": { "type": "array", "items": { "type": "string" } },
          "platform_configurations": { "type": "object" }
        }
      },
      "CreateQueueRequest": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string" },
          "description": { "type": "string" },
          "timezone": { "type": "string", "default": "UTC" },
          "brand_id": { "type": "string", "format": "uuid" },
          "is_active": { "type": "boolean", "default": true }
        }
      }
    }
  },
  "paths": {
    "/posts": {
      "get": {
        "summary": "List posts",
        "description": "Get a paginated list of posts with optional filters",
        "operationId": "listPosts",
        "tags": ["Posts"],
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string" } },
          { "name": "brand_id", "in": "query", "schema": { "type": "string", "format": "uuid" } },
          { "name": "dateFrom", "in": "query", "schema": { "type": "string", "format": "date-time" } },
          { "name": "dateTo", "in": "query", "schema": { "type": "string", "format": "date-time" } },
          { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50, "maximum": 100 } }
        ],
        "responses": {
          "200": { "description": "List of posts", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Post" } }, "page": { "type": "integer" }, "limit": { "type": "integer" } } } } } }
        }
      },
      "post": {
        "summary": "Create post",
        "description": "Create and optionally schedule a new post",
        "operationId": "createPost",
        "tags": ["Posts"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatePostRequest" } } } },
        "responses": {
          "201": { "description": "Post created", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Post" } } } } } }
        }
      }
    },
    "/posts/{id}": {
      "get": {
        "summary": "Get post",
        "operationId": "getPost",
        "tags": ["Posts"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Post details" }, "404": { "description": "Post not found" } }
      },
      "patch": {
        "summary": "Update post",
        "operationId": "updatePost",
        "tags": ["Posts"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdatePostRequest" } } } },
        "responses": { "200": { "description": "Post updated" } }
      },
      "delete": {
        "summary": "Delete post",
        "operationId": "deletePost",
        "tags": ["Posts"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Post deleted" } }
      }
    },
    "/social-accounts": {
      "get": {
        "summary": "List social accounts",
        "description": "Get all connected social media accounts",
        "operationId": "listSocialAccounts",
        "tags": ["Social Accounts"],
        "responses": { "200": { "description": "List of accounts", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/SocialAccount" } } } } } } } }
      }
    },
    "/social-accounts/{id}": {
      "get": {
        "summary": "Get social account",
        "operationId": "getSocialAccount",
        "tags": ["Social Accounts"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Account details" }, "404": { "description": "Account not found" } }
      }
    },
    "/brands": {
      "get": {
        "summary": "List brands",
        "operationId": "listBrands",
        "tags": ["Brands"],
        "responses": { "200": { "description": "List of brands", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Brand" } } } } } } } }
      }
    },
    "/brands/{id}": {
      "get": {
        "summary": "Get brand",
        "operationId": "getBrand",
        "tags": ["Brands"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Brand details" }, "404": { "description": "Brand not found" } }
      }
    },
    "/media": {
      "get": {
        "summary": "List media",
        "operationId": "listMedia",
        "tags": ["Media"],
        "responses": { "200": { "description": "List of media assets", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/MediaAsset" } } } } } } } }
      }
    },
    "/media/{id}": {
      "get": {
        "summary": "Get media",
        "operationId": "getMedia",
        "tags": ["Media"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Media details" }, "404": { "description": "Media not found" } }
      },
      "delete": {
        "summary": "Delete media",
        "operationId": "deleteMedia",
        "tags": ["Media"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Media deleted" } }
      }
    },
    "/post-results": {
      "get": {
        "summary": "List post results",
        "description": "Get publishing results for all posts",
        "operationId": "listPostResults",
        "tags": ["Post Results"],
        "responses": { "200": { "description": "List of post results", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/PostTarget" } } } } } } } }
      }
    },
    "/post-results/{id}": {
      "get": {
        "summary": "Get post result",
        "operationId": "getPostResult",
        "tags": ["Post Results"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Post result details" }, "404": { "description": "Post result not found" } }
      }
    },
    "/queues": {
      "get": {
        "summary": "List queues",
        "operationId": "listQueues",
        "tags": ["Queues"],
        "responses": { "200": { "description": "List of queues", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Queue" } } } } } } } }
      },
      "post": {
        "summary": "Create queue",
        "operationId": "createQueue",
        "tags": ["Queues"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateQueueRequest" } } } },
        "responses": { "201": { "description": "Queue created" } }
      }
    },
    "/queues/{id}": {
      "get": {
        "summary": "Get queue",
        "operationId": "getQueue",
        "tags": ["Queues"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Queue details" }, "404": { "description": "Queue not found" } }
      },
      "patch": {
        "summary": "Update queue",
        "operationId": "updateQueue",
        "tags": ["Queues"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Queue updated" } }
      },
      "delete": {
        "summary": "Delete queue",
        "operationId": "deleteQueue",
        "tags": ["Queues"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Queue deleted" } }
      }
    },
    "/queues/{id}/slots": {
      "get": {
        "summary": "List queue slots",
        "description": "Get time slots for a specific queue",
        "operationId": "listQueueSlots",
        "tags": ["Queues"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "List of queue slots", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/QueueSlot" } } } } } } } }
      }
    },
    "/posts/{id}/retry": {
      "post": {
        "summary": "Retry a failed post",
        "description": "Re-enqueue a failed post for publishing. Only post_targets currently in failed status will be retried.",
        "operationId": "retryPost",
        "tags": ["Posts"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Post requeued for publishing." } }
      }
    },
    "/media/presign": {
      "post": {
        "summary": "Get a presigned media upload URL",
        "description": "Returns a short-lived URL the client can PUT a file to directly. Call PATCH /media/{id}/complete once the upload finishes.",
        "operationId": "presignMedia",
        "tags": ["Media"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["filename","mime"], "properties": { "filename": { "type": "string" }, "mime": { "type": "string" }, "size_bytes": { "type": "integer" } } } } } },
        "responses": { "200": { "description": "Presigned upload metadata." } }
      }
    },
    "/media/{id}/complete": {
      "patch": {
        "summary": "Mark a presigned upload complete",
        "operationId": "completeMediaUpload",
        "tags": ["Media"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Media marked uploaded." } }
      }
    },
    "/accounts/health": {
      "get": {
        "summary": "Health check for all connected accounts",
        "description": "Returns per-account token validity, canPost, tokenValid, needsReconnect, issues, and a summary rollup. X probes use OAuth1-signed GET /2/users/me.",
        "operationId": "accountsHealth",
        "tags": ["Social Accounts"],
        "responses": { "200": { "description": "Health rollup with summary + accounts[]." } }
      }
    },
    "/accounts/{id}/health": {
      "get": {
        "summary": "Per-account health log",
        "operationId": "accountHealth",
        "tags": ["Social Accounts"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Recent health log entries." } }
      }
    },
    "/accounts/{id}/youtube-playlists": {
      "get": {
        "summary": "List YouTube playlists",
        "description": "Returns channel playlists plus stored defaultPlaylistId (Compose prefill only).",
        "operationId": "listYouTubePlaylists",
        "tags": ["Social Accounts"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Playlists + defaultPlaylistId." } }
      },
      "put": {
        "summary": "Set default YouTube playlist",
        "description": "Stores defaultPlaylistId / defaultPlaylistName in platform_metadata. Does not auto-apply when a post omits playlist_id.",
        "operationId": "setYouTubeDefaultPlaylist",
        "tags": ["Social Accounts"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "defaultPlaylistId": { "type": "string", "nullable": true },
                  "defaultPlaylistName": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Updated default playlist." } }
      }
    },
    "/analytics/youtube/daily-views": {
      "get": {
        "summary": "YouTube daily views",
        "operationId": "youtubeDailyViews",
        "tags": ["Analytics"],
        "parameters": [
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "videoId", "in": "query", "schema": { "type": "string" } },
          { "name": "startDate", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "endDate", "in": "query", "schema": { "type": "string", "format": "date" } }
        ],
        "responses": {
          "200": { "description": "Daily view rows." },
          "412": { "description": "Missing yt-analytics.readonly — reconnect required." }
        }
      }
    },
    "/analytics/youtube/channel-insights": {
      "get": {
        "summary": "YouTube channel insights",
        "operationId": "youtubeChannelInsights",
        "tags": ["Analytics"],
        "parameters": [
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "metrics", "in": "query", "schema": { "type": "string" } },
          { "name": "since", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "until", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "metricType", "in": "query", "schema": { "type": "string", "enum": ["total_value", "time_series"] } }
        ],
        "responses": {
          "200": { "description": "Channel metrics." },
          "412": { "description": "Missing analytics scope." }
        }
      }
    },
    "/analytics/youtube/demographics": {
      "get": {
        "summary": "YouTube audience demographics",
        "operationId": "youtubeDemographics",
        "tags": ["Analytics"],
        "parameters": [
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "videoId", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Age / gender / country breakdowns." },
          "412": { "description": "Missing analytics scope." }
        }
      }
    },
    "/accounts/{id}/gmb-locations": {
      "get": {
        "summary": "List Google Business locations",
        "operationId": "listGmbLocations",
        "tags": ["Google Business"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Locations + selectedLocationId." } }
      },
      "put": {
        "summary": "Set default Google Business location",
        "operationId": "setGmbDefaultLocation",
        "tags": ["Google Business"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Updated default location." } }
      }
    },
    "/connect/snapchat/select-profile": {
      "get": {
        "summary": "List Snapchat Public Profiles",
        "description": "Returns Public Profiles available for the connected Snapchat account. Pass accountId query param.",
        "operationId": "listSnapchatProfiles",
        "tags": ["Connect", "Snapchat"],
        "parameters": [
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "publicProfiles array + selectedProfileId + canPost.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "publicProfiles": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": { "type": "string" },
                              "display_name": { "type": "string" },
                              "username": { "type": "string" },
                              "profile_image_url": { "type": "string" },
                              "subscriber_count": { "type": "integer" }
                            }
                          }
                        },
                        "selectedProfileId": { "type": "string", "nullable": true },
                        "canPost": { "type": "boolean" }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Select Snapchat Public Profile",
        "operationId": "selectSnapchatProfile",
        "tags": ["Connect", "Snapchat"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["socialAccountId", "profileId"],
                "properties": {
                  "socialAccountId": { "type": "string", "format": "uuid" },
                  "profileId": { "type": "string" },
                  "selectedPublicProfile": {
                    "type": "object",
                    "properties": {
                      "id": { "type": "string" },
                      "display_name": { "type": "string" },
                      "username": { "type": "string" }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Profile selected; canPost true." } }
      }
    },
    "/accounts/{id}/snapchat-profiles": {
      "get": {
        "summary": "List Snapchat Public Profiles for an account",
        "operationId": "listAccountSnapchatProfiles",
        "tags": ["Snapchat"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "publicProfiles + selectedProfileId." } }
      },
      "put": {
        "summary": "Set default Snapchat Public Profile",
        "operationId": "setSnapchatDefaultProfile",
        "tags": ["Snapchat"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Updated default profile." } }
      }
    },
    "/accounts/{id}/pinterest-boards": {
      "get": {
        "summary": "List Pinterest boards",
        "description": "Returns boards plus defaultBoardId from platform_metadata. GET /accounts/{id}/boards is a discovery alias.",
        "operationId": "listPinterestBoards",
        "tags": ["Pinterest"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "boards + defaultBoardId + defaultBoardName." } }
      },
      "post": {
        "summary": "Create a Pinterest board",
        "operationId": "createPinterestBoard",
        "tags": ["Pinterest"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name"],
                "properties": {
                  "name": { "type": "string" },
                  "description": { "type": "string" },
                  "privacy": { "type": "string", "enum": ["PUBLIC", "PROTECTED", "SECRET"], "default": "PUBLIC" }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Created board." }, "502": { "description": "Upstream / duplicate board name." } }
      },
      "put": {
        "summary": "Set default Pinterest board (client prefills only)",
        "operationId": "setPinterestDefaultBoard",
        "tags": ["Pinterest"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["defaultBoardId"],
                "properties": {
                  "defaultBoardId": { "type": ["string", "null"] },
                  "defaultBoardName": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Updated default board metadata." } }
      }
    },
    "/accounts/{id}/gmb-reviews": {
      "get": {
        "summary": "List Google Business reviews",
        "operationId": "listGmbReviews",
        "tags": ["Google Business"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "locationId", "in": "query", "schema": { "type": "string" } },
          { "name": "pageToken", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Reviews page." } }
      }
    },
    "/accounts/{id}/gmb-location-details": {
      "get": { "summary": "Get GBP location details", "operationId": "getGmbLocationDetails", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "readMask", "in": "query", "schema": { "type": "string" } }, { "name": "locationId", "in": "query", "schema": { "type": "string" } }], "responses": { "200": { "description": "Location details." } } },
      "put": { "summary": "Update GBP location details", "operationId": "updateGmbLocationDetails", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Updated." } } }
    },
    "/accounts/{id}/gmb-attributes": {
      "get": { "summary": "Get GBP attributes", "operationId": "getGmbAttributes", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Attributes." } } },
      "put": { "summary": "Update GBP attributes", "operationId": "updateGmbAttributes", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Updated." } } }
    },
    "/accounts/{id}/gmb-services": {
      "get": { "summary": "Get GBP services", "operationId": "getGmbServices", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Services." } } },
      "put": { "summary": "Replace GBP services", "operationId": "updateGmbServices", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Updated." } } }
    },
    "/accounts/{id}/gmb-food-menus": {
      "get": { "summary": "Get GBP food menus", "operationId": "getGmbFoodMenus", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Menus." } } },
      "put": { "summary": "Update GBP food menus", "operationId": "updateGmbFoodMenus", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Updated." } } }
    },
    "/accounts/{id}/gmb-media": {
      "get": { "summary": "List GBP media", "operationId": "listGmbMedia", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Media items." } } },
      "post": { "summary": "Upload GBP photo", "operationId": "createGmbMedia", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "201": { "description": "Created." } } }
    },
    "/accounts/{id}/gmb-place-actions": {
      "get": { "summary": "List GBP place action links", "operationId": "listGmbPlaceActions", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Links." } } },
      "post": { "summary": "Create GBP place action link", "operationId": "createGmbPlaceAction", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "201": { "description": "Created." } } }
    },
    "/accounts/{id}/gmb-verifications": {
      "get": { "summary": "Get GBP verification state", "operationId": "getGmbVerifications", "tags": ["Google Business"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Voice of Merchant + history." } } }
    },
    "/analytics/googlebusiness/performance": {
      "get": {
        "summary": "Google Business location performance",
        "description": "Daily metrics time series. Per-post insights are not available.",
        "operationId": "gmbPerformance",
        "tags": ["Analytics"],
        "parameters": [
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "locationId", "in": "query", "schema": { "type": "string" } },
          { "name": "metrics", "in": "query", "schema": { "type": "string" } },
          { "name": "startDate", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "endDate", "in": "query", "schema": { "type": "string", "format": "date" } }
        ],
        "responses": { "200": { "description": "Multi daily metric series." } }
      }
    },
    "/analytics/googlebusiness/search-keywords": {
      "get": {
        "summary": "Google Business search keywords",
        "operationId": "gmbSearchKeywords",
        "tags": ["Analytics"],
        "parameters": [
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "locationId", "in": "query", "schema": { "type": "string" } },
          { "name": "startMonth", "in": "query", "schema": { "type": "string" } },
          { "name": "endMonth", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Keyword impression counts." } }
      }
    },
    "/twitter/retweet": {
      "post": {
        "summary": "Retweet a post",
        "description": "POST /2/users/:id/retweets via OAuth 1.0a. Consumes X Pay-Per-Use credits.",
        "operationId": "twitterRetweet",
        "tags": ["Twitter"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["accountId", "tweetId"],
                "properties": {
                  "accountId": { "type": "string", "format": "uuid" },
                  "tweetId": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Retweet created." },
          "429": { "description": "X rate limit." }
        }
      },
      "delete": {
        "summary": "Undo retweet",
        "operationId": "twitterUndoRetweet",
        "tags": ["Twitter"],
        "parameters": [
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "tweetId", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Retweet removed." } }
      }
    },
    "/twitter/bookmark": {
      "post": {
        "summary": "Bookmark a post",
        "operationId": "twitterBookmark",
        "tags": ["Twitter"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["accountId", "tweetId"],
                "properties": {
                  "accountId": { "type": "string", "format": "uuid" },
                  "tweetId": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Bookmarked." } }
      },
      "delete": {
        "summary": "Remove bookmark",
        "operationId": "twitterUndoBookmark",
        "tags": ["Twitter"],
        "parameters": [
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "tweetId", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Bookmark removed." } }
      }
    },
    "/twitter/like": {
      "post": {
        "summary": "Like a post",
        "operationId": "twitterLike",
        "tags": ["Twitter"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["accountId", "tweetId"],
                "properties": {
                  "accountId": { "type": "string", "format": "uuid" },
                  "tweetId": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Liked." } }
      },
      "delete": {
        "summary": "Unlike a post",
        "operationId": "twitterUnlike",
        "tags": ["Twitter"],
        "parameters": [
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "tweetId", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Unliked." } }
      }
    },
    "/connect/{platform}/start": {
      "post": {
        "summary": "Start a headless OAuth connection",
        "description": "Returns a connect_token and either an authorize URL (for OAuth platforms) or a fields list (for manual platforms like Telegram/Discord). Pass headless=true to receive a token without browser redirect.",
        "operationId": "connectStart",
        "tags": ["Connect"],
        "parameters": [
          { "name": "platform", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "headless", "in": "query", "schema": { "type": "boolean" } }
        ],
        "responses": { "200": { "description": "Connect token + next-step instructions." } }
      }
    },
    "/inbox/conversations": {
      "get": {
        "summary": "List conversations",
        "description": "Fetch DM conversations from connected messaging accounts (Zernio-compatible). Aggregated + filtered by profile/platform/status. Supported: Facebook, Instagram, Twitter/X, Bluesky, Reddit, Telegram, WhatsApp. Encrypted X Chat threads are not available via the X API.",
        "operationId": "listInboxConversations",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "platform", "in": "query", "schema": { "type": "string", "enum": ["facebook", "instagram", "twitter", "bluesky", "reddit", "telegram", "whatsapp"] } },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["active", "archived"] } },
          { "name": "sortOrder", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50, "minimum": 1, "maximum": 100 } },
          { "name": "cursor", "in": "query", "schema": { "type": "string" } },
          { "name": "accountId", "in": "query", "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Aggregated conversations",
            "content": {
              "application/json": {
                "example": {
                  "data": [{ "id": "conv_platform_id", "platform": "instagram", "accountId": "acc_uuid", "participantName": "Alex", "lastMessage": "Hi!", "status": "active", "unreadCount": 1 }],
                  "pagination": { "hasMore": false, "nextCursor": null },
                  "meta": { "accountsQueried": 2, "accountsFailed": 0, "failedAccounts": [], "lastUpdated": "2026-07-24T12:00:00Z" }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create conversation",
        "description": "Start a DM with a recipient. Supported: Instagram, Facebook, WhatsApp (freeform into existing window), Telegram, Discord. X/Bluesky/Reddit/WA templates return PLATFORM_NOT_SUPPORTED until configured.",
        "operationId": "createInboxConversation",
        "tags": ["Inbox"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["accountId"],
                "properties": {
                  "accountId": { "type": "string", "format": "uuid" },
                  "participantId": { "type": "string" },
                  "participantUsername": { "type": "string" },
                  "message": { "type": "string" },
                  "attachmentUrl": { "type": "string" },
                  "templateName": { "type": "string", "description": "WhatsApp only (not yet implemented)" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Conversation created / message sent" },
          "400": { "description": "PLATFORM_NOT_SUPPORTED / TEMPLATE_REQUIRED / validation" }
        }
      }
    },
    "/inbox/conversations/search": {
      "get": {
        "summary": "Search conversations",
        "description": "Search message text (token match) and contact identity (name/username/phone substring). Bluesky is not searchable.",
        "operationId": "searchInboxConversations",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "query", "in": "query", "required": true, "schema": { "type": "string", "minLength": 2, "maxLength": 200 } },
          { "name": "direction", "in": "query", "schema": { "type": "string", "enum": ["incoming", "outgoing"] } },
          { "name": "platform", "in": "query", "schema": { "type": "string" } },
          { "name": "accountId", "in": "query", "schema": { "type": "string", "format": "uuid" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 50 } }
        ],
        "responses": { "200": { "description": "Matching conversations" } }
      }
    },
    "/inbox/conversations/{conversationId}": {
      "get": {
        "summary": "Get conversation",
        "description": "Requires accountId. conversationId may be platform_conversation_id or inbox uuid.",
        "operationId": "getInboxConversation",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": { "200": { "description": "Conversation details" }, "404": { "description": "Not found" } }
      },
      "put": {
        "summary": "Update conversation status",
        "description": "Archive or activate. Body: { accountId, status: active|archived }",
        "operationId": "updateInboxConversation",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Updated" } }
      }
    },
    "/inbox/conversations/{conversationId}/read": {
      "post": {
        "summary": "Mark conversation as read",
        "description": "Marks unread incoming messages as read. Does not side-effect on GET messages.",
        "operationId": "markConversationRead",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "required": ["accountId"], "properties": { "accountId": { "type": "string" } } } } }
        },
        "responses": { "200": { "description": "{ success, markedCount }" } }
      }
    },
    "/inbox/conversations/{conversationId}/typing": {
      "post": {
        "summary": "Send typing indicator",
        "description": "Best-effort typing indicator. Always returns 200; platform send is no-op until Meta/Telegram wiring.",
        "operationId": "sendTypingIndicator",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "{ success: true }" } }
      }
    },
    "/inbox/conversations/{conversationId}/messages": {
      "get": {
        "summary": "List messages",
        "description": "Cursor pagination. Default sortOrder=asc (chat style). Read-only — does not mark read.",
        "operationId": "listInboxMessages",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 100, "maximum": 100 } },
          { "name": "cursor", "in": "query", "schema": { "type": "string" } },
          { "name": "sortOrder", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"], "default": "asc" } }
        ],
        "responses": { "200": { "description": "Messages page" } }
      },
      "post": {
        "summary": "Send message",
        "description": "Send text/attachment in a conversation. Instagram, Facebook, WhatsApp, Telegram, Discord via sendDm.",
        "operationId": "sendInboxMessage",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["accountId"],
                "properties": {
                  "accountId": { "type": "string" },
                  "message": { "type": "string" },
                  "attachmentUrl": { "type": "string" },
                  "attachmentType": { "type": "string", "enum": ["image", "video", "audio", "file"] }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Sent" }, "400": { "description": "PLATFORM_LIMITATION" } }
      }
    },
    "/inbox/conversations/{conversationId}/messages/{messageId}": {
      "patch": {
        "summary": "Edit message",
        "description": "Telegram only (stub until bot edit is wired).",
        "operationId": "editInboxMessage",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "messageId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "400": { "description": "Not supported / not configured" } }
      },
      "delete": {
        "summary": "Delete message",
        "description": "Soft-delete locally for Telegram/X/Bluesky/Reddit. Meta/WhatsApp return 400.",
        "operationId": "deleteInboxMessage",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "messageId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "{ success: true }" } }
      }
    },
    "/inbox/conversations/{conversationId}/messages/{messageId}/reactions": {
      "post": {
        "summary": "Add reaction",
        "description": "Telegram/WhatsApp only — platform wiring pending.",
        "operationId": "addMessageReaction",
        "tags": ["Inbox"],
        "responses": { "400": { "description": "Not supported / not wired" } }
      },
      "delete": {
        "summary": "Remove reaction",
        "operationId": "removeMessageReaction",
        "tags": ["Inbox"],
        "responses": { "400": { "description": "Not supported / not wired" } }
      }
    },
    "/media/upload-direct": {
      "post": {
        "summary": "Upload media file (direct)",
        "description": "Multipart file upload with Bearer API key. Returns public URL for attachmentUrl. Max 25MB.",
        "operationId": "uploadMediaDirect",
        "tags": ["Media"],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["file"],
                "properties": {
                  "file": { "type": "string", "format": "binary" },
                  "contentType": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Uploaded",
            "content": {
              "application/json": {
                "example": { "url": "https://…", "filename": "…", "contentType": "image/jpeg", "size": 12345 }
              }
            }
          }
        }
      }
    },
    "/inbox/comments": {
      "get": {
        "summary": "List commented posts",
        "description": "Returns posts with comment counts across connected accounts (Zernio-compatible). Use ?flat=1 for raw inbox_comments rows. Call POST /inbox/sync first for YouTube.",
        "operationId": "listCommentedPosts",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "platform", "in": "query", "schema": { "type": "string", "enum": ["youtube", "facebook", "instagram", "threads", "linkedin", "x", "bluesky", "reddit"] } },
          { "name": "accountId", "in": "query", "schema": { "type": "string", "format": "uuid" } },
          { "name": "minComments", "in": "query", "schema": { "type": "integer", "minimum": 0 } },
          { "name": "sortBy", "in": "query", "schema": { "type": "string", "enum": ["date", "comments"], "default": "date" } },
          { "name": "sortOrder", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50, "maximum": 100 } },
          { "name": "flat", "in": "query", "schema": { "type": "string", "enum": ["1"] }, "description": "Return flat comment rows instead of posts" }
        ],
        "responses": {
          "200": {
            "description": "Commented posts",
            "content": {
              "application/json": {
                "example": {
                  "data": [{ "id": "VIDEO_ID", "platform": "youtube", "accountId": "acc_uuid", "commentCount": 12, "content": "Video title" }],
                  "pagination": { "hasMore": false, "nextCursor": null }
                }
              }
            }
          }
        }
      }
    },
    "/inbox/comments/{postId}": {
      "get": {
        "summary": "Get post comments",
        "description": "Fetch comments for a specific post. Requires accountId query parameter.",
        "operationId": "getPostComments",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Platform post/video ID" },
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": {
            "description": "Comments for the post",
            "content": {
              "application/json": {
                "example": {
                  "status": "success",
                  "comments": [{ "id": "COMMENT_ID", "message": "Great video!", "platform": "youtube", "canReply": true, "replies": [] }],
                  "meta": { "platform": "youtube", "postId": "VIDEO_ID", "accountId": "acc_uuid" }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Reply to comment or post",
        "description": "Requires accountId + message. Optional commentId to reply to a specific comment.",
        "operationId": "replyToInboxPost",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["accountId", "message"],
                "properties": {
                  "accountId": { "type": "string", "format": "uuid" },
                  "message": { "type": "string" },
                  "commentId": { "type": "string", "description": "Platform comment ID to reply to" }
                }
              },
              "example": { "accountId": "acc_uuid", "commentId": "COMMENT_ID", "message": "Thanks for your feedback!" }
            }
          }
        },
        "responses": { "200": { "description": "Reply posted" } }
      },
      "delete": {
        "summary": "Delete comment",
        "description": "Requires accountId and commentId query parameters. Supported on YouTube, Facebook, Instagram, and more.",
        "operationId": "deleteInboxComment",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "commentId", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Deleted" } }
      }
    },
    "/inbox/comments/{postId}/{commentId}/moderation": {
      "post": {
        "summary": "Set YouTube comment moderation status",
        "description": "YouTube only. published | rejected | heldForReview. Optional banAuthor when rejected.",
        "operationId": "setCommentModeration",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "commentId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "accountId": "acc_uuid",
                "platform": "youtube",
                "moderationStatus": "heldForReview",
                "banAuthor": false
              }
            }
          }
        },
        "responses": { "200": { "description": "Applied" }, "400": { "description": "platform_not_supported" }, "502": { "description": "YouTube rejected" } }
      }
    },
    "/inbox/comments/{postId}/{commentId}/hide": {
      "post": {
        "summary": "Hide comment",
        "description": "Facebook, Instagram, Threads (and YouTube hold-for-review via hide).",
        "operationId": "hideInboxComment",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "commentId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "example": { "accountId": "acc_uuid" } } }
        },
        "responses": { "200": { "description": "Hidden" } }
      },
      "delete": {
        "summary": "Unhide comment",
        "operationId": "unhideInboxComment",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "commentId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": { "200": { "description": "Unhidden" } }
      }
    },
    "/inbox/comments/{postId}/{commentId}/like": {
      "post": {
        "summary": "Like comment",
        "operationId": "likeInboxComment",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "commentId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "content": { "application/json": { "example": { "accountId": "acc_uuid" } } }
        },
        "responses": { "200": { "description": "Liked" } }
      },
      "delete": {
        "summary": "Unlike comment",
        "operationId": "unlikeInboxComment",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "commentId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "accountId", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": { "200": { "description": "Unliked" } }
      }
    },
    "/inbox/comments/{postId}/{commentId}/private-reply": {
      "post": {
        "summary": "Send private reply (comment-to-DM)",
        "description": "Instagram and Facebook only.",
        "operationId": "sendPrivateReplyToComment",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "commentId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": { "accountId": "acc_uuid", "message": "Thanks — sent you a DM!" }
            }
          }
        },
        "responses": { "200": { "description": "Sent" }, "400": { "description": "PLATFORM_LIMITATION" } }
      }
    },
    "/inbox/comments/{id}/reply": {
      "post": {
        "summary": "Reply by inbox UUID (legacy)",
        "operationId": "replyInboxCommentByUuid",
        "tags": ["Inbox"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "example": { "message": "Thanks!" } } }
        },
        "responses": { "200": { "description": "Replied" } }
      }
    },
    "/inbox/sync": {
      "post": {
        "summary": "Sync inbox from platforms",
        "description": "Pulls recent comments (and Meta DMs) into PostRoutine. YouTube uses commentThreads.list on recent channel videos. Optional body: { \"account_id\": \"uuid\" }.",
        "operationId": "syncInbox",
        "tags": ["Inbox"],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "account_id": { "type": "string", "format": "uuid" },
                  "social_account_id": { "type": "string", "format": "uuid" }
                }
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync result",
            "content": {
              "application/json": {
                "example": { "ok": true, "accounts": 1, "synced": 42 }
              }
            }
          }
        }
      }
    },
    "/inbox/labels": {
      "get": { "summary": "List inbox labels", "operationId": "listInboxLabels", "tags": ["Inbox"], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create inbox label", "operationId": "createInboxLabel", "tags": ["Inbox"], "responses": { "201": { "description": "Created" } } }
    },
    "/inbox/saved-replies": {
      "get": { "summary": "List saved replies", "operationId": "listSavedReplies", "tags": ["Inbox"], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create saved reply", "operationId": "createSavedReply", "tags": ["Inbox"], "responses": { "201": { "description": "Created" } } }
    },
    "/inbox/items/{type}/{id}/labels": {
      "post": { "summary": "Attach label to inbox item", "operationId": "attachInboxLabel", "tags": ["Inbox"], "parameters": [{ "name": "type", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "201": { "description": "Attached" } } },
      "delete": { "summary": "Detach label from inbox item", "operationId": "detachInboxLabel", "tags": ["Inbox"], "parameters": [{ "name": "type", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "label_id", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Detached" } } }
    },
    "/inbox/items/{type}/{id}/assign": {
      "post": { "summary": "Assign inbox item to teammate", "operationId": "assignInboxItem", "tags": ["Inbox"], "parameters": [{ "name": "type", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Assigned" } } },
      "delete": { "summary": "Unassign inbox item", "operationId": "unassignInboxItem", "tags": ["Inbox"], "parameters": [{ "name": "type", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Unassigned" } } }
    },
    "/inbox/mark-all-read": {
      "post": { "summary": "Mark all inbox items read", "operationId": "markAllInboxRead", "tags": ["Inbox"], "responses": { "200": { "description": "OK" } } }
    },
    "/inbox/ai-reply": {
      "post": { "summary": "Generate AI reply draft in brand voice", "operationId": "inboxAiReply", "tags": ["Inbox"], "responses": { "200": { "description": "Draft text" } } }
    },
    "/contacts": {
      "get": { "summary": "List contacts", "operationId": "listContacts", "tags": ["Growth"], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create contact", "operationId": "createContact", "tags": ["Growth"], "responses": { "201": { "description": "Created" } } }
    },
    "/contacts/bulk": {
      "post": { "summary": "Bulk-create contacts", "operationId": "bulkCreateContacts", "tags": ["Growth"], "responses": { "200": { "description": "Bulk result" } } }
    },
    "/contacts/{id}": {
      "get": { "summary": "Get contact", "operationId": "getContact", "tags": ["Growth"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "OK" } } },
      "patch": { "summary": "Update contact", "operationId": "updateContact", "tags": ["Growth"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "OK" } } },
      "delete": { "summary": "Delete contact", "operationId": "deleteContact", "tags": ["Growth"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "OK" } } }
    },
    "/broadcasts": {
      "get": { "summary": "List broadcasts", "operationId": "listBroadcasts", "tags": ["Growth"], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create broadcast", "operationId": "createBroadcast", "tags": ["Growth"], "responses": { "201": { "description": "Created" } } }
    },
    "/sequences": {
      "get": { "summary": "List sequences", "operationId": "listSequences", "tags": ["Growth"], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create sequence", "operationId": "createSequence", "tags": ["Growth"], "responses": { "201": { "description": "Created" } } }
    },
    "/comment-automations": {
      "get": { "summary": "List comment automations", "operationId": "listCommentAutomations", "tags": ["Growth"], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create comment automation", "operationId": "createCommentAutomation", "tags": ["Growth"], "responses": { "201": { "description": "Created" } } }
    },
    "/ice-breakers": {
      "get": { "summary": "List ice-breakers", "operationId": "listIceBreakers", "tags": ["Growth"], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create ice-breaker", "operationId": "createIceBreaker", "tags": ["Growth"], "responses": { "201": { "description": "Created" } } }
    },
    "/telegram-commands": {
      "get": { "summary": "List Telegram bot commands", "operationId": "listTelegramCommands", "tags": ["Growth"], "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create Telegram command", "operationId": "createTelegramCommand", "tags": ["Growth"], "responses": { "201": { "description": "Created" } } }
    },
    "/communications/capabilities": {
      "get": { "summary": "Get enabled communications provider capabilities", "operationId": "getCommunicationCapabilities", "tags": ["Communications"], "x-required-scope": "communications:read", "responses": { "200": { "description": "Truthful capability matrix" }, "403": { "description": "Private beta or add-on is not enabled" } } }
    },
    "/communications/settings": {
      "get": { "summary": "Get communications compliance and spend settings", "operationId": "getCommunicationSettings", "tags": ["Communications"], "x-required-scope": "communications:read", "responses": { "200": { "description": "Settings" } } },
      "patch": { "summary": "Update quiet hours, geo controls and spend limit", "operationId": "updateCommunicationSettings", "tags": ["Communications"], "x-required-scope": "communications:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Updated" } } }
    },
    "/communications/numbers": {
      "get": { "summary": "List phone numbers", "operationId": "listPhoneNumbers", "tags": ["Communications"], "x-required-scope": "communications:read", "responses": { "200": { "description": "Numbers" } } },
      "post": { "summary": "Create a number draft or purchase when provider capability exists", "operationId": "createPhoneNumber", "tags": ["Communications"], "x-required-scope": "communications:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Created" }, "501": { "description": "Provider capability unavailable" } } }
    },
    "/communications/sender-ids": {
      "get": { "summary": "List sender IDs", "operationId": "listSenderIds", "tags": ["Communications"], "x-required-scope": "communications:read", "responses": { "200": { "description": "Sender IDs" } } },
      "post": { "summary": "Create a sender ID draft", "operationId": "createSenderId", "tags": ["Communications"], "x-required-scope": "communications:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Created" } } }
    },
    "/communications/messages": {
      "get": { "summary": "List SMS, MMS and WhatsApp messages", "operationId": "listCommunicationMessages", "tags": ["Communications"], "x-required-scope": "communications:read", "responses": { "200": { "description": "Messages" } } },
      "post": { "summary": "Create a message draft or queue through a supported provider", "operationId": "createCommunicationMessage", "tags": ["Communications"], "x-required-scope": "communications:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Created" }, "409": { "description": "Opt-out, quiet-hours or spend-limit denial" }, "501": { "description": "Provider capability unavailable" } } }
    },
    "/communications/calls": {
      "get": { "summary": "List call logs and recording metadata", "operationId": "listCommunicationCalls", "tags": ["Communications"], "x-required-scope": "communications:read", "responses": { "200": { "description": "Calls" } } }
    },
    "/communications/calls/session": {
      "post": { "summary": "Create a browser calling session when provider supports it", "operationId": "createBrowserCallSession", "tags": ["Communications"], "x-required-scope": "communications:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "501": { "description": "Provider capability unavailable" } } }
    },
    "/communications/opt-outs": {
      "get": { "summary": "List communication opt-outs", "operationId": "listCommunicationOptOuts", "tags": ["Communications"], "x-required-scope": "communications:read", "responses": { "200": { "description": "Opt-outs" } } },
      "post": { "summary": "Record an opt-out", "operationId": "createCommunicationOptOut", "tags": ["Communications"], "x-required-scope": "communications:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Recorded" } } }
    },
    "/communications/usage": {
      "get": { "summary": "List communications usage ledger", "operationId": "listCommunicationUsage", "tags": ["Communications"], "x-required-scope": "communications:read", "responses": { "200": { "description": "Usage" } } }
    },
    "/workflows": {
      "get": { "summary": "List versioned workflows", "operationId": "listWorkflows", "tags": ["Workflows"], "x-required-scope": "workflows:read", "responses": { "200": { "description": "Workflows" } } },
      "post": { "summary": "Create a workflow and first immutable version", "operationId": "createWorkflow", "tags": ["Workflows"], "x-required-scope": "workflows:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Created" } } }
    },
    "/workflows/{id}": {
      "get": { "summary": "Get a workflow and version history", "operationId": "getWorkflow", "tags": ["Workflows"], "x-required-scope": "workflows:read", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Workflow" } } },
      "patch": { "summary": "Update workflow state or create a new version", "operationId": "updateWorkflow", "tags": ["Workflows"], "x-required-scope": "workflows:write", "parameters": [{ "$ref": "#/components/parameters/Id" }, { "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Updated" } } }
    },
    "/workflows/{id}/trigger": {
      "post": { "summary": "Queue a manual workflow execution", "operationId": "triggerWorkflow", "tags": ["Workflows"], "x-required-scope": "workflows:write", "parameters": [{ "$ref": "#/components/parameters/Id" }, { "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "202": { "description": "Execution queued" } } }
    },
    "/workflows/{id}/executions": {
      "get": { "summary": "List workflow executions and correlation IDs", "operationId": "listWorkflowExecutions", "tags": ["Workflows"], "x-required-scope": "workflows:read", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Executions" } } }
    },
    "/ads/accounts": {
      "get": { "summary": "List connected ad accounts and health", "operationId": "listAdAccounts", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" }, "402": { "description": "ads_addon_required" } } }
    },
    "/ads/accounts/connect": {
      "post": { "summary": "Discover ad accounts from an existing OAuth connection", "operationId": "connectAdAccounts", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Connected" }, "422": { "description": "Provider does not support account discovery" } } }
    },
    "/ads/accounts/{id}/status": {
      "get": { "summary": "Get ad account connection health and capabilities", "operationId": "getAdAccountStatus", "tags": ["Ads"], "x-required-scope": "ads:read", "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Connection status" } } }
    },
    "/ads/accounts/{id}/sync": {
      "post": { "summary": "Synchronize a supported provider account", "operationId": "syncAdAccount", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Synchronized" }, "422": { "description": "Provider sync unsupported" } } }
    },
    "/ads/providers": {
      "get": { "summary": "List provider capabilities and limitations", "operationId": "listAdsProviderCapabilities", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "Provider capability matrix" } } }
    },
    "/ads/campaigns": {
      "get": { "summary": "List ad campaigns", "operationId": "listAdCampaigns", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create a campaign draft or push to a supported provider", "operationId": "createAdCampaign", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Created" } } }
    },
    "/ads/campaigns/{id}": {
      "get": { "summary": "Get an ad campaign", "operationId": "getAdCampaign", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "patch": { "summary": "Update campaign status, budget or fields", "operationId": "updateAdCampaign", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Updated" } } },
      "delete": { "summary": "Delete a local campaign draft", "operationId": "deleteAdCampaign", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Deleted" } } }
    },
    "/ads/ad-sets": {
      "get": { "summary": "List ad sets", "operationId": "listAdSets", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create an ad set draft", "operationId": "createAdSet", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Created" } } }
    },
    "/ads/ad-sets/{id}": {
      "get": { "summary": "Get an ad set", "operationId": "getAdSet", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "patch": { "summary": "Update an ad set draft, targeting, status or budget", "operationId": "updateAdSet", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Updated" } } },
      "delete": { "summary": "Delete an ad set draft", "operationId": "deleteAdSet", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Deleted" } } }
    },
    "/ads/ads": {
      "get": { "summary": "List ads", "operationId": "listAds", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create an ad draft", "operationId": "createAd", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Created" } } }
    },
    "/ads/ads/{id}": {
      "get": { "summary": "Get an ad", "operationId": "getAd", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "patch": { "summary": "Update an ad draft or status", "operationId": "updateAd", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Updated" } } },
      "delete": { "summary": "Delete an ad draft", "operationId": "deleteAd", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Deleted" } } }
    },
    "/ads/creatives": {
      "get": { "summary": "List ad creatives", "operationId": "listAdCreatives", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create an ad creative draft", "operationId": "createAdCreative", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Created" } } }
    },
    "/ads/creatives/{id}": {
      "get": { "summary": "Get an ad creative", "operationId": "getAdCreative", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "patch": { "summary": "Update an ad creative draft", "operationId": "updateAdCreative", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Updated" } } },
      "delete": { "summary": "Delete an ad creative draft", "operationId": "deleteAdCreative", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Deleted" } } }
    },
    "/ads/{id}/boost-post": {
      "post": {
        "summary": "Boost an organic post",
        "operationId": "boostPost", "tags": ["Ads"], "x-required-scope": "ads:write",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "$ref": "#/components/parameters/IdempotencyKey" }],
        "responses": { "201": { "description": "Local boost draft created" }, "422": { "description": "Provider boost unsupported" } }
      }
    },
    "/ads/{id}/analytics": {
      "get": {
        "summary": "Daily campaign analytics",
        "operationId": "campaignAnalytics", "tags": ["Ads"], "x-required-scope": "ads:read",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "since", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "until", "in": "query", "schema": { "type": "string", "format": "date" } }
        ],
        "responses": { "200": { "description": "Metrics window" } }
      }
    },
    "/ads/audiences": {
      "get": { "summary": "List custom audiences", "operationId": "listAdAudiences", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "post": { "summary": "Create a local custom audience draft", "operationId": "createAdAudience", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "201": { "description": "Created" } } }
    },
    "/ads/audiences/{id}": {
      "get": { "summary": "Get a custom audience", "operationId": "getAdAudience", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "OK" } } },
      "patch": { "summary": "Update a custom audience draft", "operationId": "updateAdAudience", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Updated" } } },
      "delete": { "summary": "Delete a custom audience draft", "operationId": "deleteAdAudience", "tags": ["Ads"], "x-required-scope": "ads:write", "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }], "responses": { "200": { "description": "Deleted" } } }
    },
    "/ads/metrics": {
      "get": { "summary": "List spend, impression and click timeline metrics", "operationId": "listAdMetrics", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "Metrics timeline" } } }
    },
    "/ads/leads": {
      "get": { "summary": "List persisted provider leads", "operationId": "listAdLeads", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "Leads" } } }
    },
    "/ads/previews": {
      "get": { "summary": "List persisted ad previews", "operationId": "listAdPreviews", "tags": ["Ads"], "x-required-scope": "ads:read", "responses": { "200": { "description": "Previews" } } }
    },
    "/ads/interest-search": {
      "get": {
        "summary": "Search ad targeting interests",
        "operationId": "interestSearch", "tags": ["Ads"], "x-required-scope": "ads:read",
        "parameters": [
          { "name": "platform", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "q", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Suggestions" } }
      }
    },
    "/analytics": {
      "get": { "summary": "List post analytics", "operationId": "listAnalytics", "tags": ["Analytics"], "parameters": [{ "name": "timeframe", "in": "query", "schema": { "type": "string", "default": "90" } }, { "name": "account_id", "in": "query", "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Paginated post analytics and overview" } } }
    },
    "/analytics/sync": {
      "post": { "summary": "Synchronize analytics", "operationId": "syncAnalytics", "tags": ["Analytics"], "responses": { "200": { "description": "Synchronization result" } } }
    },
    "/analytics/overview": {
      "get": { "summary": "Get analytics overview", "operationId": "getAnalyticsOverview", "tags": ["Analytics"], "responses": { "200": { "description": "Workspace analytics overview" } } }
    },
    "/analytics/daily-metrics": {
      "get": { "summary": "Get daily metrics", "operationId": "getDailyMetrics", "tags": ["Analytics"], "responses": { "200": { "description": "Daily analytics series" } } }
    },
    "/analytics/best-time": {
      "get": { "summary": "Get best posting times", "operationId": "getBestTime", "tags": ["Analytics"], "responses": { "200": { "description": "Best posting slots and heatmap" } } }
    },
    "/analytics/{accountId}": {
      "get": { "summary": "Get account analytics", "operationId": "getAccountAnalytics", "tags": ["Analytics"], "parameters": [{ "name": "accountId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Account analytics" } } }
    },
    "/reports": {
      "get": { "summary": "List analytics reports", "operationId": "listReports", "tags": ["Analytics"], "responses": { "200": { "description": "Persisted reports" } } },
      "post": { "summary": "Create analytics report", "operationId": "createReport", "tags": ["Analytics"], "responses": { "201": { "description": "Report created" } } }
    },
    "/reports/{id}": {
      "get": { "summary": "Get analytics report", "operationId": "getReport", "tags": ["Analytics"], "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Report" } } },
      "delete": { "summary": "Delete analytics report", "operationId": "deleteReport", "tags": ["Analytics"], "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Report deleted" } } }
    },
    "/reports/{id}/export": {
      "get": { "summary": "Export analytics report", "operationId": "exportReport", "tags": ["Analytics"], "parameters": [{ "$ref": "#/components/parameters/Id" }, { "name": "format", "in": "query", "schema": { "type": "string", "enum": ["json", "csv", "html", "pdf"] } }], "responses": { "200": { "description": "Report export" } } }
    },
    "/reports/{id}/share": {
      "post": { "summary": "Create report share link", "operationId": "shareReport", "tags": ["Analytics"], "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Expiring public report token" } } }
    },
    "/users": {
      "get": { "summary": "List workspace users", "operationId": "listUsers", "tags": ["Admin"], "x-required-scope": "users:read", "responses": { "200": { "description": "Workspace users with roles and profile access" }, "403": { "$ref": "#/components/responses/Forbidden" } } },
      "post": { "summary": "Invite workspace user", "description": "Returns the invite token once.", "operationId": "inviteUser", "tags": ["Admin"], "x-required-scope": "users:write", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "role": { "$ref": "#/components/schemas/WorkspaceRole" }, "brand_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } }, "expires_at": { "type": "string", "format": "date-time" } } } } } }, "responses": { "201": { "description": "Invite created" } } }
    },
    "/users/{id}": {
      "patch": { "summary": "Update user role and profile access", "operationId": "updateUser", "tags": ["Admin"], "x-required-scope": "users:write", "parameters": [{ "$ref": "#/components/parameters/Id" }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "role": { "$ref": "#/components/schemas/WorkspaceRole" }, "brand_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } } } } } } }, "responses": { "200": { "description": "Updated member" }, "403": { "$ref": "#/components/responses/Forbidden" } } },
      "delete": { "summary": "Remove workspace user", "operationId": "removeUser", "tags": ["Admin"], "x-required-scope": "users:write", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "User removed" }, "403": { "$ref": "#/components/responses/Forbidden" } } }
    },
    "/teams": {
      "get": { "summary": "Get current team workspace", "operationId": "getTeam", "tags": ["Admin"], "x-required-scope": "teams:read", "responses": { "200": { "description": "Current workspace and caller role" } } }
    },
    "/api-keys": {
      "get": { "summary": "List API keys", "operationId": "listApiKeys", "tags": ["Developer Admin"], "x-required-scope": "keys:read", "responses": { "200": { "description": "Redacted API key metadata" }, "403": { "$ref": "#/components/responses/Forbidden" } } },
      "post": { "summary": "Issue API key", "description": "The plaintext key is returned once in the creation response.", "operationId": "issueApiKey", "tags": ["Developer Admin"], "x-required-scope": "keys:write", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssueApiKeyRequest" } } } }, "responses": { "201": { "description": "Key issued; copy the key now" }, "403": { "$ref": "#/components/responses/Forbidden" } } }
    },
    "/api-keys/{id}/rotate": {
      "post": { "summary": "Rotate API key", "description": "Invalidates the prior key and returns the replacement once.", "operationId": "rotateApiKey", "tags": ["Developer Admin"], "x-required-scope": "keys:write", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Key rotated" }, "403": { "$ref": "#/components/responses/Forbidden" } } }
    },
    "/api-keys/{id}": {
      "delete": { "summary": "Revoke API key", "operationId": "revokeApiKey", "tags": ["Developer Admin"], "x-required-scope": "keys:write", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Key revoked" }, "403": { "$ref": "#/components/responses/Forbidden" } } }
    },
    "/webhooks": {
      "get": { "summary": "List webhooks", "description": "Signing secrets are never returned by list operations.", "operationId": "listWebhooks", "tags": ["Webhooks"], "x-required-scope": "webhooks:read", "responses": { "200": { "description": "Redacted webhook metadata" } } },
      "post": { "summary": "Create webhook", "description": "The signing secret is returned once.", "operationId": "createWebhook", "tags": ["Webhooks"], "x-required-scope": "webhooks:write", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookRequest" } } } }, "responses": { "201": { "description": "Webhook created" } } }
    },
    "/webhooks/{id}": {
      "get": { "summary": "Get webhook", "operationId": "getWebhook", "tags": ["Webhooks"], "x-required-scope": "webhooks:read", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Redacted webhook metadata" } } },
      "patch": { "summary": "Update webhook", "operationId": "updateWebhook", "tags": ["Webhooks"], "x-required-scope": "webhooks:write", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Webhook updated" } } },
      "delete": { "summary": "Delete webhook", "operationId": "deleteWebhook", "tags": ["Webhooks"], "x-required-scope": "webhooks:write", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Webhook deleted" } } }
    },
    "/webhooks/{id}/test": {
      "post": { "summary": "Send test webhook", "operationId": "testWebhook", "tags": ["Webhooks"], "x-required-scope": "webhooks:write", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Synchronous delivery result" } } }
    },
    "/webhooks/{id}/logs": {
      "get": { "summary": "List webhook delivery logs", "operationId": "listWebhookLogs", "tags": ["Webhooks"], "x-required-scope": "webhooks:read", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Recent delivery attempts" } } }
    },
    "/webhooks/{id}/rotate-secret": {
      "post": { "summary": "Rotate webhook signing secret", "description": "Returns the new signing secret once.", "operationId": "rotateWebhookSecret", "tags": ["Webhooks"], "x-required-scope": "webhooks:write", "parameters": [{ "$ref": "#/components/parameters/Id" }], "responses": { "200": { "description": "Secret rotated" } } }
    },
    "/webhook-logs": {
      "get": { "summary": "List all webhook delivery logs", "operationId": "listAllWebhookLogs", "tags": ["Webhooks"], "x-required-scope": "logs:read", "responses": { "200": { "description": "Recent workspace delivery attempts" } } }
    },
    "/activity-logs": {
      "get": { "summary": "List unified activity logs", "operationId": "listActivityLogs", "tags": ["Admin"], "x-required-scope": "logs:read", "parameters": [{ "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } }], "responses": { "200": { "description": "Recent workspace activity" } } }
    },
    "/usage": {
      "get": { "summary": "Get monthly usage snapshot", "operationId": "getUsage", "tags": ["Billing"], "x-required-scope": "billing:read", "responses": { "200": { "description": "Current-period usage counters" } } }
    },
    "/workspace": {
      "get": { "summary": "Get workspace", "operationId": "getWorkspace", "tags": ["Admin"], "x-required-scope": "workspace:read", "responses": { "200": { "description": "Workspace metadata" } } },
      "patch": { "summary": "Update workspace", "operationId": "updateWorkspace", "tags": ["Admin"], "x-required-scope": "workspace:write", "responses": { "200": { "description": "Workspace updated" } } }
    },
    "/workspace/settings": {
      "get": { "summary": "Get workspace settings", "operationId": "getWorkspaceSettings", "tags": ["Admin"], "x-required-scope": "workspace:read", "responses": { "200": { "description": "Workspace settings" } } },
      "patch": { "summary": "Update workspace settings", "operationId": "updateWorkspaceSettings", "tags": ["Admin"], "x-required-scope": "workspace:write", "responses": { "200": { "description": "Workspace settings updated" } } }
    },
    "/ai-providers": {
      "get": { "summary": "List AI provider metadata", "description": "Provider API keys are write-only and never returned.", "operationId": "listAiProviders", "tags": ["Developer Admin"], "x-required-scope": "ai-providers:read", "responses": { "200": { "description": "Provider metadata with key_last_four only" } } }
    },
    "/ai-providers/{provider}": {
      "put": { "summary": "Set encrypted BYO provider key", "description": "The supplied api_key is encrypted using token-crypto before storage and never returned.", "operationId": "setAiProvider", "tags": ["Developer Admin"], "x-required-scope": "ai-providers:write", "parameters": [{ "name": "provider", "in": "path", "required": true, "schema": { "type": "string" } }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["api_key"], "properties": { "api_key": { "type": "string", "writeOnly": true }, "model": { "type": "string" }, "is_active": { "type": "boolean" } } } } } }, "responses": { "200": { "description": "Provider metadata" } } },
      "delete": { "summary": "Delete AI provider credential", "operationId": "deleteAiProvider", "tags": ["Developer Admin"], "x-required-scope": "ai-providers:write", "parameters": [{ "name": "provider", "in": "path", "required": true, "schema": { "type": "string" } }], "responses": { "200": { "description": "Provider removed" } } }
    }
  },
  "tags": [
    { "name": "Posts", "description": "Create, read, update, and delete posts. Schedule or publish immediately." },
    { "name": "Social Accounts", "description": "View connected social media accounts." },
    { "name": "Brands", "description": "View workspace brands." },
    { "name": "Media", "description": "Manage media assets." },
    { "name": "Post Results", "description": "View publishing results and errors." },
    { "name": "Queues", "description": "Manage posting queues and time slots." },
    { "name": "Connect", "description": "OAuth and manual platform connection flows. Use these to add/remove accounts programmatically." },
    { "name": "Growth", "description": "Contacts, broadcasts, sequences, ice-breakers, and Telegram bot commands. Requires Growth plan tier." },
    { "name": "Ads", "description": "Cross-platform ads manager: campaigns, ad sets, ads, creatives, audiences and daily metrics. Requires Ads add-on." },
    { "name": "Inbox", "description": "Social inbox: comments, DMs, labels, assignments, saved replies, and AI-assisted replies. Requires Inbox add-on." },
    { "name": "Admin", "description": "Workspace users, teams, settings, activity, and access control." },
    { "name": "Developer Admin", "description": "API credentials and encrypted provider configuration. Admin role and granular scopes required." },
    { "name": "Webhooks", "description": "Webhook endpoints, test deliveries, logs, and signing-secret rotation." },
    { "name": "Billing", "description": "Usage and billing-manager endpoints." },
    { "name": "Analytics", "description": "Organic analytics, synchronization, and persisted reports." }
  ]
}