openapi: 3.1.0
info:
  title: Flipbook API
  version: "1.0.0"
  summary: Create, manage, and share flipbooks programmatically.
  description: |
    The Flipbook API lets agents and LLMs turn ordered image sets into beautiful,
    embeddable flipbooks. Pay-as-you-go: $1.00 USD per flipbook created via API.
  contact:
    name: Flipbook API
    url: https://flipbook.it.com/agents
servers:
  - url: https://urmuupgjgyacsuvmqyhc.supabase.co/functions/v1/api-v1
    description: Production
security:
  - BearerAuth: []
  - {}   # Anonymous access is permitted for public GET endpoints.
tags:
  - name: Flipbooks
paths:
  /flipbooks:
    post:
      tags: [Flipbooks]
      summary: Create a flipbook
      operationId: createFlipbook
      parameters:
        - in: header
          name: Idempotency-Key
          schema: { type: string, format: uuid }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CreateFlipbookRequest' }
      responses:
        "201": { description: Created, content: { application/json: { schema: { $ref: '#/components/schemas/Flipbook' } } } }
        "400": { $ref: '#/components/responses/Error' }
        "401": { $ref: '#/components/responses/Error' }
        "429": { $ref: '#/components/responses/Error' }
    get:
      tags: [Flipbooks]
      summary: List flipbooks
      operationId: listFlipbooks
      description: |
        With a Bearer key: lists flipbooks owned by that key's user (including private).
        Without a key: lists public flipbooks across the platform. Anonymous responses omit `page_urls`.
      security:
        - BearerAuth: []
        - {}
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: '#/components/schemas/Flipbook' }
                  next_cursor: { type: string, nullable: true }
  /flipbooks/{id}:
    parameters:
      - in: path
        name: id
        required: true
        schema: { type: string }
    get:
      tags: [Flipbooks]
      summary: Get a flipbook
      operationId: getFlipbook
      description: |
        Public flipbooks are readable without a key. Private flipbooks require the owner's Bearer key.
        The `id` path parameter accepts either the flipbook UUID or the slug for anonymous requests.
      security:
        - BearerAuth: []
        - {}
      responses:
        "200": { description: OK, content: { application/json: { schema: { $ref: '#/components/schemas/Flipbook' } } } }
    patch:
      tags: [Flipbooks]
      summary: Update a flipbook
      operationId: updateFlipbook
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/UpdateFlipbookRequest' }
      responses:
        "200": { description: OK, content: { application/json: { schema: { $ref: '#/components/schemas/Flipbook' } } } }
    delete:
      tags: [Flipbooks]
      summary: Delete a flipbook
      operationId: deleteFlipbook
      responses:
        "200": { description: Deleted }
  /flipbooks/{id}/embed:
    parameters:
      - in: path
        name: id
        required: true
        schema: { type: string }
    get:
      tags: [Flipbooks]
      summary: Get embed URL and HTML snippet
      operationId: getEmbedCode
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  embed_url: { type: string, format: uri }
                  embed_html: { type: string }
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: fk_live_*
  schemas:
    CreateFlipbookRequest:
      type: object
      required: [title, pages]
      properties:
        title: { type: string, maxLength: 200 }
        description: { type: string, maxLength: 2000, nullable: true }
        pages:
          type: array
          minItems: 1
          maxItems: 500
          items: { type: string, format: uri }
          description: Ordered array of page image URLs (JPG/PNG/WebP).
        is_public: { type: boolean, default: true }
    UpdateFlipbookRequest:
      type: object
      properties:
        title: { type: string }
        description: { type: string, nullable: true }
        slug: { type: string }
        is_public: { type: boolean }
    Flipbook:
      type: object
      properties:
        id: { type: string, format: uuid }
        slug: { type: string }
        title: { type: string }
        description: { type: string, nullable: true }
        page_count: { type: integer }
        cover_url: { type: string, format: uri, nullable: true }
        page_urls: { type: array, items: { type: string, format: uri } }
        is_public: { type: boolean }
        view_count: { type: integer }
        created_at: { type: string, format: date-time }
        url: { type: string, format: uri }
        embed_url: { type: string, format: uri }
  responses:
    Error:
      description: Error
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: object
                properties:
                  code: { type: string }
                  message: { type: string }
                  param: { type: string }