{
  "openapi": "3.1.0",
  "info": {
    "title": "UGCBloom API",
    "description": "## What is UGCBloom?\n\nUGCBloom is a UGC (user-generated content) marketing platform. Brands create **campaigns** with budgets and briefs, then **creators** join those campaigns and submit **videos**. Videos go through a review workflow: `submitted` → `approved`/`rejected` → `live` (posted to social media). Creators earn payouts when videos are approved, plus performance bonuses based on views, likes, and comments.\n\n## What this API does\n\nThis is a **read-only** API that gives brands programmatic access to all their campaign data. It is scoped to your organization — you can only see your own campaigns, creators, and videos.\n\n## Key concepts\n\n- **Campaign**: A branded content initiative with a budget, brief, and target platforms (TikTok, Instagram, etc.)\n- **Creator**: A content creator who participates in campaigns and submits videos\n- **Video**: A content submission by a creator, with a status workflow and per-platform performance stats\n- **Payout**: Money earned by creators for approved videos and performance bonuses\n- **CPM**: Cost per mille — total spend divided by views, multiplied by 1000\n\n## Common workflows for AI agents\n\n1. **Campaign overview**: Call `GET /campaigns` to list all campaigns, then `GET /campaigns/{id}/stats` for performance metrics\n2. **Creator analysis**: Call `GET /campaigns/{id}/creators?sort=total_views&order=desc` to find top creators\n3. **Performance ranking**: Call `GET /campaigns/{id}/leaderboard?sort=views` for ranked video performance\n4. **Trend monitoring**: Call `GET /stats/historical?days=30` for daily metrics over time\n5. **Video audit**: Call `GET /campaigns/{id}/videos?status=live` to see all live videos with their stats\n6. **ROI analysis**: Call `GET /campaigns/{id}/stats` to get CPM and total spend vs. views\n7. **Message review**: Call `GET /conversations` to list all DM threads, then `GET /conversations/{id}/messages` to read messages (requires 'messages' scope)\n\n## Scopes\n\nAPI keys support multiple scopes:\n- `read` (always included): Access to campaigns, creators, videos, stats, and leaderboards\n- `messages` (optional): Access to direct message conversations and message history\n\n## Authentication\n\nPass your API key as a Bearer token: `Authorization: Bearer ugcb_live_...`\nCreate API keys in your UGCBloom dashboard under Settings > API Keys.",
    "version": "1.0.0",
    "contact": {
      "name": "UGCBloom Support",
      "url": "https://ugcbloom.com"
    }
  },
  "servers": [
    {
      "url": "https://ugcbloom.com/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key obtained from Settings > API Keys in your UGCBloom dashboard. Pass as: Authorization: Bearer ugcb_live_..."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string", "example": "not_found" },
              "message": { "type": "string", "example": "Campaign not found" }
            },
            "required": ["code", "message"]
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "page": { "type": "integer", "example": 1 },
          "per_page": { "type": "integer", "example": 25 },
          "total": { "type": "integer", "example": 42 }
        }
      },
      "Campaign": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "logo_url": { "type": "string", "nullable": true },
          "brief_url": { "type": "string", "nullable": true },
          "budget": { "type": "number" },
          "initial_budget": { "type": "number" },
          "platforms": { "type": "array", "items": { "type": "string" } },
          "status": { "type": "string", "enum": ["draft", "requires_payment", "active", "under_review", "ended", "disapproved"] },
          "archived": { "type": "boolean", "description": "True if the campaign has been archived" },
          "videos_count": { "type": "integer" },
          "max_submissions_per_creator": { "type": "integer" },
          "max_spend_per_video": { "type": "number" },
          "languages": { "type": "array", "items": { "type": "string" } },
          "geos": { "type": "array", "items": { "type": "string" } },
          "created_at": { "type": "string", "format": "date-time" },
          "activated_at": { "type": "string", "format": "date-time", "nullable": true },
          "archived_at": { "type": "string", "format": "date-time", "nullable": true }
        }
      },
      "CampaignDetail": {
        "allOf": [
          { "$ref": "#/components/schemas/Campaign" },
          {
            "type": "object",
            "properties": {
              "campaign_type": { "type": "string", "enum": ["open", "approval_required", "invite_only"] },
              "min_platforms": { "type": "integer" },
              "geo_strict": { "type": "boolean" }
            }
          }
        ]
      },
      "CampaignStats": {
        "type": "object",
        "properties": {
          "campaign_id": { "type": "string", "format": "uuid" },
          "budget": { "type": "number" },
          "initial_budget": { "type": "number" },
          "total_creators": { "type": "integer" },
          "total_videos": { "type": "integer" },
          "videos_by_status": {
            "type": "object",
            "additionalProperties": { "type": "integer" },
            "example": { "submitted": 5, "approved": 12, "live": 8 }
          },
          "total_views": { "type": "integer" },
          "total_likes": { "type": "integer" },
          "total_comments": { "type": "integer" },
          "total_spend": { "type": "number" },
          "total_creator_payout": { "type": "number" },
          "cpm": { "type": "number", "description": "Cost per mille (cost per 1000 views)" }
        }
      },
      "CreatorAccount": {
        "type": "object",
        "properties": {
          "platform": { "type": "string" },
          "username": { "type": "string" },
          "followers": { "type": "integer" },
          "profile_url": { "type": "string", "nullable": true }
        }
      },
      "CampaignCreator": {
        "type": "object",
        "properties": {
          "creator_id": { "type": "string" },
          "display_name": { "type": "string" },
          "country": { "type": "string", "nullable": true },
          "blocked": { "type": "boolean" },
          "approval_status": { "type": "string", "nullable": true },
          "accounts": { "type": "array", "items": { "$ref": "#/components/schemas/CreatorAccount" } },
          "videos_count": { "type": "integer" },
          "videos_by_status": { "type": "object", "additionalProperties": { "type": "integer" } },
          "total_views": { "type": "integer" },
          "total_likes": { "type": "integer" },
          "total_comments": { "type": "integer" },
          "total_payout": { "type": "number" }
        }
      },
      "CampaignCreatorDetail": {
        "allOf": [
          { "$ref": "#/components/schemas/CampaignCreator" },
          {
            "type": "object",
            "properties": {
              "videos": { "type": "array", "items": { "$ref": "#/components/schemas/Video" } }
            }
          }
        ]
      },
      "PlatformStats": {
        "type": "object",
        "properties": {
          "platform": { "type": "string" },
          "views": { "type": "integer" },
          "likes": { "type": "integer" },
          "comments": { "type": "integer" },
          "shares": { "type": "integer" }
        }
      },
      "Video": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "creator_id": { "type": "string" },
          "status": { "type": "string", "enum": ["submitted", "approved", "rejected", "live", "resubmitted"] },
          "submission_date": { "type": "string", "format": "date-time", "nullable": true },
          "video_url": { "type": "string", "nullable": true },
          "social_media_links": { "type": "object", "nullable": true },
          "updated_at": { "type": "string", "format": "date-time" },
          "stats": {
            "type": "object",
            "properties": {
              "total_views": { "type": "integer" },
              "total_likes": { "type": "integer" },
              "total_comments": { "type": "integer" },
              "total_shares": { "type": "integer" },
              "by_platform": { "type": "array", "items": { "$ref": "#/components/schemas/PlatformStats" } }
            }
          }
        }
      },
      "LeaderboardEntry": {
        "type": "object",
        "properties": {
          "rank": { "type": "integer" },
          "video_id": { "type": "string", "format": "uuid" },
          "creator_id": { "type": "string" },
          "creator_name": { "type": "string" },
          "video_url": { "type": "string", "nullable": true },
          "views": { "type": "integer" },
          "likes": { "type": "integer" },
          "comments": { "type": "integer" },
          "payout": { "type": "number" }
        }
      },
      "OrgStats": {
        "type": "object",
        "properties": {
          "total_campaigns": { "type": "integer" },
          "campaigns_by_status": { "type": "object", "additionalProperties": { "type": "integer" } },
          "total_creators": { "type": "integer" },
          "total_videos": { "type": "integer" },
          "total_budget": { "type": "number" },
          "total_initial_budget": { "type": "number" },
          "total_spend": { "type": "number" },
          "total_views": { "type": "integer" },
          "total_likes": { "type": "integer" },
          "total_comments": { "type": "integer" },
          "cpm": { "type": "number" }
        }
      },
      "DailyStats": {
        "type": "object",
        "properties": {
          "date": { "type": "string", "format": "date" },
          "metrics": { "type": "object", "description": "Daily aggregated metrics" }
        }
      },
      "ConversationParticipant": {
        "type": "object",
        "properties": {
          "user_id": { "type": "string" },
          "display_name": { "type": "string" },
          "is_org_member": { "type": "boolean", "description": "True if this participant is a member of your organization, false if they are a creator" }
        }
      },
      "Conversation": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string", "nullable": true, "description": "Group chat name, null for 1:1 conversations" },
          "created_at": { "type": "string", "format": "date-time" },
          "participants": { "type": "array", "items": { "$ref": "#/components/schemas/ConversationParticipant" } },
          "last_message": {
            "type": "object",
            "nullable": true,
            "properties": {
              "content": { "type": "string" },
              "sender_id": { "type": "string" },
              "created_at": { "type": "string", "format": "date-time" }
            }
          }
        }
      },
      "MessageReaction": {
        "type": "object",
        "properties": {
          "emoji": { "type": "string" },
          "count": { "type": "integer" }
        }
      },
      "MessageAttachment": {
        "type": "object",
        "nullable": true,
        "properties": {
          "url": { "type": "string" },
          "name": { "type": "string" },
          "size": { "type": "integer", "description": "File size in bytes" },
          "type": { "type": "string", "description": "MIME type" }
        }
      },
      "Message": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "sender_id": { "type": "string" },
          "sender_name": { "type": "string" },
          "sender_is_org_member": { "type": "boolean", "description": "True if the sender is from your organization" },
          "content": { "type": "string" },
          "created_at": { "type": "string", "format": "date-time" },
          "is_pinned": { "type": "boolean" },
          "parent_message_id": { "type": "string", "format": "uuid", "nullable": true, "description": "ID of the parent message if this is a thread reply" },
          "attachment": { "$ref": "#/components/schemas/MessageAttachment" },
          "reactions": { "type": "array", "items": { "$ref": "#/components/schemas/MessageReaction" } }
        }
      }
    },
    "parameters": {
      "page": {
        "name": "page",
        "in": "query",
        "schema": { "type": "integer", "default": 1, "minimum": 1 },
        "description": "Page number for pagination"
      },
      "per_page": {
        "name": "per_page",
        "in": "query",
        "schema": { "type": "integer", "default": 25, "minimum": 1, "maximum": 100 },
        "description": "Number of items per page (max 100)"
      },
      "search": {
        "name": "search",
        "in": "query",
        "schema": { "type": "string" },
        "description": "Search by name or title"
      },
      "sort": {
        "name": "sort",
        "in": "query",
        "schema": { "type": "string" },
        "description": "Field to sort by"
      },
      "order": {
        "name": "order",
        "in": "query",
        "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" },
        "description": "Sort order"
      }
    }
  },
  "x-agent-instructions": "To get started, call listCampaigns to see all available campaigns. Each campaign has an id you can use with other endpoints. For a quick performance snapshot, call getCampaignStats with the campaign id. To find the best-performing creators or videos, use the leaderboard endpoint. For organization-wide metrics, use getOrgStats. To read direct messages between the brand team and creators, call listConversations then getConversationMessages (requires the 'messages' scope on your API key). All monetary values are in USD. All timestamps are ISO 8601 UTC. API keys have scopes: 'read' (campaigns, stats, creators, videos) is always included; 'messages' (conversations and DMs) is optional.",
  "paths": {
    "/campaigns": {
      "get": {
        "operationId": "listCampaigns",
        "summary": "List all campaigns",
        "description": "Returns a paginated list of all campaigns belonging to your organization. Supports filtering by status and searching by title. This is typically the first endpoint an agent should call to discover available campaigns. Use the campaign `id` from the response to call other campaign-specific endpoints.",
        "tags": ["Campaigns"],
        "parameters": [
          { "$ref": "#/components/parameters/page" },
          { "$ref": "#/components/parameters/per_page" },
          { "$ref": "#/components/parameters/search" },
          { "$ref": "#/components/parameters/sort" },
          { "$ref": "#/components/parameters/order" },
          {
            "name": "status",
            "in": "query",
            "schema": { "type": "string", "enum": ["draft", "requires_payment", "active", "under_review", "ended", "disapproved"] },
            "description": "Filter by campaign status"
          }
        ],
        "responses": {
          "200": {
            "description": "List of campaigns",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Campaign" } },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" }
                  }
                }
              }
            }
          },
          "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "Rate limited" }
        }
      }
    },
    "/campaigns/{campaignId}": {
      "get": {
        "operationId": "getCampaign",
        "summary": "Get campaign details",
        "description": "Returns full details for a single campaign including brief URL, brand guidelines, and example content.",
        "tags": ["Campaigns"],
        "parameters": [
          { "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Campaign details",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/CampaignDetail" } } } } }
          },
          "404": { "description": "Campaign not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/campaigns/{campaignId}/stats": {
      "get": {
        "operationId": "getCampaignStats",
        "summary": "Get campaign statistics",
        "description": "Returns aggregated statistics for a campaign including total views, likes, comments, spend, CPM, and video status breakdown. This is the best endpoint for getting a quick performance overview of a campaign. The `videos_by_status` field shows how many videos are in each workflow stage. CPM (cost per mille) measures cost-efficiency — lower CPM means better value per view.",
        "tags": ["Campaigns"],
        "parameters": [
          { "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Campaign statistics",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/CampaignStats" } } } } }
          },
          "404": { "description": "Campaign not found" }
        }
      }
    },
    "/campaigns/{campaignId}/creators": {
      "get": {
        "operationId": "listCampaignCreators",
        "summary": "List creators in a campaign",
        "description": "Returns creators participating in a campaign with their performance metrics, video counts, and social accounts. Supports searching by name and filtering by status (active/blocked). Each creator includes their total views, likes, comments, payout amount, and number of videos by status. Use `sort=total_views&order=desc` to rank creators by performance. The `blocked` field indicates if a creator has been blocked from submitting more videos.",
        "tags": ["Creators"],
        "parameters": [
          { "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "$ref": "#/components/parameters/page" },
          { "$ref": "#/components/parameters/per_page" },
          { "$ref": "#/components/parameters/search" },
          { "$ref": "#/components/parameters/sort" },
          { "$ref": "#/components/parameters/order" },
          {
            "name": "status",
            "in": "query",
            "schema": { "type": "string", "enum": ["active", "blocked"] },
            "description": "Filter creators by status"
          }
        ],
        "responses": {
          "200": {
            "description": "List of creators",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/CampaignCreator" } },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" }
                  }
                }
              }
            }
          },
          "404": { "description": "Campaign not found" }
        }
      }
    },
    "/campaigns/{campaignId}/creators/{creatorId}": {
      "get": {
        "operationId": "getCampaignCreator",
        "summary": "Get creator details in a campaign",
        "description": "Returns detailed information about a specific creator in a campaign, including all their video submissions with stats.",
        "tags": ["Creators"],
        "parameters": [
          { "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "creatorId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Creator details with videos",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/CampaignCreatorDetail" } } } } }
          },
          "404": { "description": "Creator not found in this campaign" }
        }
      }
    },
    "/campaigns/{campaignId}/videos": {
      "get": {
        "operationId": "listCampaignVideos",
        "summary": "List videos in a campaign",
        "description": "Returns all video submissions for a campaign with their performance stats broken down by platform. Supports filtering by video status.",
        "tags": ["Videos"],
        "parameters": [
          { "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "$ref": "#/components/parameters/page" },
          { "$ref": "#/components/parameters/per_page" },
          { "$ref": "#/components/parameters/sort" },
          { "$ref": "#/components/parameters/order" },
          {
            "name": "status",
            "in": "query",
            "schema": { "type": "string", "enum": ["submitted", "approved", "rejected", "live", "resubmitted"] },
            "description": "Filter by video status"
          }
        ],
        "responses": {
          "200": {
            "description": "List of videos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Video" } },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" }
                  }
                }
              }
            }
          },
          "404": { "description": "Campaign not found" }
        }
      }
    },
    "/campaigns/{campaignId}/videos/{videoId}": {
      "get": {
        "operationId": "getCampaignVideo",
        "summary": "Get video details",
        "description": "Returns a single video submission with full platform-level performance statistics.",
        "tags": ["Videos"],
        "parameters": [
          { "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "videoId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Video details",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Video" } } } } }
          },
          "404": { "description": "Video not found" }
        }
      }
    },
    "/campaigns/{campaignId}/leaderboard": {
      "get": {
        "operationId": "getCampaignLeaderboard",
        "summary": "Get creator leaderboard",
        "description": "Returns a ranked list of top-performing videos in a campaign, ordered by the chosen metric. Each entry includes the video's creator name, view/like/comment counts, and total payout. Use `sort=views` for reach-based ranking, `sort=payout` for spend-based ranking, or `sort=likes` for engagement-based ranking. This is the best endpoint for quickly identifying top-performing content.",
        "tags": ["Campaigns"],
        "parameters": [
          { "name": "campaignId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "default": 25, "minimum": 1, "maximum": 100 },
            "description": "Number of entries to return"
          },
          {
            "name": "sort",
            "in": "query",
            "schema": { "type": "string", "enum": ["views", "likes", "comments", "payout"], "default": "views" },
            "description": "Metric to rank by"
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked leaderboard",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/LeaderboardEntry" } } } } } }
          },
          "404": { "description": "Campaign not found" }
        }
      }
    },
    "/stats": {
      "get": {
        "operationId": "getOrgStats",
        "summary": "Get organization-wide statistics",
        "description": "Returns aggregated statistics across ALL campaigns in your organization. This gives a high-level overview: total campaigns, unique creators, total videos, total budget allocated, total amount spent, total views/likes/comments, and overall CPM. Use this for executive summaries or dashboard overviews. For per-campaign breakdowns, use getCampaignStats on individual campaigns.",
        "tags": ["Statistics"],
        "responses": {
          "200": {
            "description": "Organization statistics",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/OrgStats" } } } } }
          }
        }
      }
    },
    "/stats/historical": {
      "get": {
        "operationId": "getHistoricalStats",
        "summary": "Get historical statistics",
        "description": "Returns daily aggregated statistics for your organization over a configurable time period (1-365 days, default 30). Each entry contains a date and a metrics object with that day's aggregated numbers. Use this for building time-series charts, detecting trends, or comparing week-over-week performance. For a single snapshot in time, use getOrgStats instead.",
        "tags": ["Statistics"],
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "schema": { "type": "integer", "default": 30, "minimum": 1, "maximum": 365 },
            "description": "Number of days of history to return"
          }
        ],
        "responses": {
          "200": {
            "description": "Daily statistics",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/DailyStats" } } } } } }
          }
        }
      }
    },
    "/conversations": {
      "get": {
        "operationId": "listConversations",
        "summary": "List direct message conversations",
        "description": "Returns all direct message conversations involving your organization's members. Each conversation includes participant info and the last message. Requires the `messages` scope on your API key. Conversations may be 1:1 (brand member to creator) or group chats. The `is_org_member` flag on participants tells you which side of the conversation is your team vs. external creators.",
        "tags": ["Messages"],
        "parameters": [
          { "$ref": "#/components/parameters/page" },
          { "$ref": "#/components/parameters/per_page" }
        ],
        "responses": {
          "200": {
            "description": "List of conversations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Conversation" } },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" }
                  }
                }
              }
            }
          },
          "403": { "description": "API key does not have the messages scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/conversations/{conversationId}/messages": {
      "get": {
        "operationId": "getConversationMessages",
        "summary": "Get messages in a conversation",
        "description": "Returns paginated messages from a specific conversation, newest first. Each message includes sender info, content, attachments, reactions, and thread parent reference. Requires the `messages` scope. The `sender_is_org_member` flag tells you whether each message was sent by your team or by a creator.",
        "tags": ["Messages"],
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "$ref": "#/components/parameters/page" },
          { "$ref": "#/components/parameters/per_page" }
        ],
        "responses": {
          "200": {
            "description": "List of messages",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Message" } },
                    "meta": { "$ref": "#/components/schemas/PaginationMeta" }
                  }
                }
              }
            }
          },
          "403": { "description": "API key does not have the messages scope" },
          "404": { "description": "Conversation not found or not accessible" }
        }
      }
    }
  }
}
