openapi: 3.1.0
info:
  title: KiVio Creator API
  description: |
    Manage your KiVio creator account from ChatGPT. Create series, list your uploads,
    respond to parent-paid commission requests, chat with commissioning parents,
    see earnings, and request admin deletion of live videos.

    Not included in this schema: direct video file upload (ChatGPT Actions can't
    stream multipart bytes reliably). Use the KiVio MCP server for Claude Code
    if you want to upload AI-generated video files from your local disk.
  version: 1.0.0
  contact:
    name: KiVio
    url: https://kidsaivideo.com
    email: support@kidsaivideo.com
servers:
  - url: https://api.kidsaivideo.com
    description: Production
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        A long-lived (90-day) creator session token. Mint one at
        https://kidsaivideo.com/creator/dashboard → "Link external tools" →
        "Generate ChatGPT API key". Rotate anytime from the same panel.
  schemas:
    SeriesCreateInput:
      type: object
      required: [title, totalEpisodesPlanned]
      properties:
        title: { type: string, maxLength: 200 }
        totalEpisodesPlanned: { type: integer, minimum: 1, maximum: 500 }
        description: { type: string, maxLength: 2000 }
        releaseDate: { type: string, format: date-time, nullable: true }
        isExclusive: { type: boolean }
        commissionBucket:
          type: string
          enum: [NONE, PUBLIC_COMMISSION, PRIVATE_COMMISSION]
    CommissionCounterBody:
      type: object
      required: [offerCoins]
      properties:
        offerCoins: { type: integer, minimum: 1, maximum: 500000 }
    CommissionDeliverBody:
      type: object
      required: [videoId]
      properties:
        videoId: { type: string, format: uuid }
    ChatReplyBody:
      type: object
      required: [body]
      properties:
        body: { type: string, minLength: 1, maxLength: 2000 }
    DeletionRequestBody:
      type: object
      required: [reason]
      properties:
        reason: { type: string, minLength: 10, maxLength: 1000 }
security:
  - bearerAuth: []
paths:
  /creator/me:
    get:
      operationId: whoami
      summary: Return the signed-in creator's profile + wallet balances.
      responses:
        '200': { description: Creator profile with wallet totals. }
  /creator/series:
    get:
      operationId: list_series
      summary: List every series owned by the signed-in creator.
      responses:
        '200': { description: Array of series with episode counts + commission bucket flags. }
    post:
      operationId: create_series
      summary: Create a new series. isExclusive and commissionBucket are locked at creation.
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/SeriesCreateInput' }
      responses:
        '200': { description: Newly created series row. }
  /creator/videos:
    get:
      operationId: list_videos
      summary: List the creator's uploads with pipeline status, view counts, and series.
      parameters:
        - in: query
          name: seriesId
          schema: { type: string, format: uuid }
        - in: query
          name: state
          schema:
            type: string
            enum: [INTAKE, QUALITY_CHECK, MODERATION, SAFE_LIVE, REJECTED]
      responses:
        '200': { description: Array of video rows. }
  /creator/commissions:
    get:
      operationId: list_commissions
      summary: List commissions addressed to this creator with status + brief.
      responses:
        '200': { description: Array of commission rows. }
  /creator/commissions/{id}/accept:
    post:
      operationId: accept_commission
      summary: Accept a PROPOSED commission. Debits the parent, starts a 14-day deliver window.
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, format: uuid }
      responses:
        '200': { description: Accepted commission state. }
  /creator/commissions/{id}/counter:
    post:
      operationId: counter_commission
      summary: Counter the price on a PROPOSED commission.
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, format: uuid }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CommissionCounterBody' }
      responses:
        '200': { description: Updated commission state. }
  /creator/commissions/{id}/reject:
    post:
      operationId: reject_commission
      summary: Reject a PROPOSED commission (terminal).
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, format: uuid }
      responses:
        '200': { description: Rejected commission state. }
  /creator/commissions/{id}/deliver:
    post:
      operationId: deliver_commission
      summary: Attach a delivery video to an ACCEPTED commission. Video must be in a commission-bucket series.
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, format: uuid }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CommissionDeliverBody' }
      responses:
        '200': { description: Delivery recorded. }
  /creator/dm/threads/{id}/messages:
    post:
      operationId: reply_in_thread
      summary: Send a chat reply in a DM thread with a parent. Server scrubs contact info.
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, format: uuid }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/ChatReplyBody' }
      responses:
        '200': { description: Message id + scrubbing report. }
  /creator/videos/{id}/deletion-request:
    post:
      operationId: request_video_deletion
      summary: Submit a SAFE_LIVE video for admin removal with a short reason.
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, format: uuid }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/DeletionRequestBody' }
      responses:
        '200': { description: Deletion-request row id. }
