# -------------------------------
# Info:
# -------------------------------
# Basic structure: https://swagger.io/docs/specification/basic-structure
# Examples: https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/petstore.yaml
# -------------------------------
# Auth:
# -------------------------------
# Use either:
#  - headers (commented out)
#  - securitySchemes + security
# -------------------------------

openapi: "3.1.0"
info:
  version: 1.1.0
  title: Ocoya API
  description: REST API reference for Ocoya.
x-readme:
  explorer-enabled: true
  # Proxy to allow testing from frontend ("Try it" button)
  proxy-enabled: true
  metrics-enabled: true
  samples-languages:
    - curl
    - javascript
    - node
    - python
    - php
#  headers:
#    - key: X-API-Key
#      value: <your_access_token>

servers:
  - url: https://app.ocoya.com/api/_public/v1

paths:
  /me:
    get:
      summary: Me
      description: Returns information about authenticated user.
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error

  /workspaces:
    get:
      summary: List all owned workspaces
      description: Returns information about all owned workspaces
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error

  /social-profiles:
    get:
      summary: List all connected social profiles
      description: Returns information about all connected social profiles
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error

  /social-profiles/connection-url:
    post:
      summary: Generate social connection URL
      description: Returns a browser URL that starts connecting a social network to a workspace. Open the returned URL while signed in to Ocoya to approve OAuth and select profiles.
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [provider]
              properties:
                provider:
                  type: string
                  description: Social network used for the connection flow.
                  enum: [facebook, instagram, x, linkedin, pinterest]
                  example: instagram
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  url:
                    type: string
                    description: Browser URL to open while signed in to Ocoya to start the connection flow.
                    example: https://app.ocoya.com/api/social-connect/start?provider=instagram&workspaceId=cmayvq3hk00017apshay5qezu
                required: [url]
        '400':
          description: Unsupported provider
        '500':
          description: Unknown error

  /brand-kits:
    get:
      summary: List brand kits
      description: Returns brand kits in a workspace so you can pass a brand kit ID to AI post or campaign generation.
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
        - in: query
          name: query
          description: Search query used to filter results by name or matching text.
          schema:
            type: string
            example: Acme
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error

  /hashtag-libraries:
    get:
      summary: List hashtag libraries
      description: Returns reusable hashtag libraries in a workspace so you can pass a hashtag library ID to AI post or campaign generation.
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
        - in: query
          name: query
          description: Search query used to filter results by name or matching text.
          schema:
            type: string
            example: Launch
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error

  /studio-templates:
    get:
      summary: List Studio templates
      description: Returns Studio templates that can be used as visual references for AI-generated posts.
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
        - in: query
          name: query
          description: Search query used to filter results by name or matching text.
          schema:
            type: string
            example: Launch
        - in: query
          name: page
          description: Zero-based page number for paginated results.
          schema:
            type: integer
            example: 0
        - in: query
          name: perPage
          description: Maximum number of items to return per page.
          schema:
            type: integer
            example: 20
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error

  /post:
    get:
      summary: List all posts
      description: Returns information about all posts
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
        - in: query
          name: statuses
          description: Post statuses to include in the result.
          schema:
            type: array
            enum: [GENERATING, DRAFT, PENDING_CLIENT_APPROVAL, PENDING_INTERNAL_APPROVAL, SCHEDULED, POSTED, ERROR]
            example: [ DRAFT ]
          style: form
          explode: true
        - in: query
          name: page
          description: Zero-based page number for paginated results.
          schema:
            type: integer
            example: 0
        - in: query
          name: perPage
          description: Maximum number of items to return per page.
          schema:
            type: integer
            example: 10
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error
    post:
      summary: Create a scheduled or a draft post
      description: Returns an id of the post
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  required:
                    - caption
                    - mediaUrls
                  properties:
                    caption:
                      type: string
                      description: Text caption for the post.
                      example: Happy new year everyone!
                    mediaUrls:
                      type: array
                      description: Publicly accessible media URLs to attach to the post.
                      example: [ "https://yourmediaurl.com" ]
                    socialProfileIds:
                      type: array
                      description: Connected social profile IDs that should receive the post. Get IDs from `GET /social-profiles`.
                      example: [ "clh49poxf008x8kov4ncbjty9" ]
                    scheduledAt:
                      type: string
                      description: ISO 8601 datetime when the post should be scheduled. Omit to save as draft.
                      example: "2024-01-01T00:00:00Z"
                - type: object
                  required:
                    - caption
                  properties:
                    caption:
                      type: string
                      description: Text caption for the post.
                      example: Happy new year everyone!
                    socialProfileIds:
                      type: array
                      description: Connected social profile IDs that should receive the post. Get IDs from `GET /social-profiles`.
                      example: [ "clh49poxf008x8kov4ncbjty9" ]
                    scheduledAt:
                      type: string
                      description: ISO 8601 datetime when the post should be scheduled. Omit to save as draft.
                      example: "2024-01-01T00:00:00Z"
                - type: object
                  required:
                    - mediaUrls
                  properties:
                    mediaUrls:
                      type: array
                      description: Publicly accessible media URLs to attach to the post.
                      example: [ "https://yourmediaurl.com" ]
                    socialProfileIds:
                      type: array
                      description: Connected social profile IDs that should receive the post. Get IDs from `GET /social-profiles`.
                      example: [ "clh49poxf008x8kov4ncbjty9" ]
                    scheduledAt:
                      type: string
                      description: ISO 8601 datetime when the post should be scheduled. Omit to save as draft.
                      example: "2024-01-01T00:00:00Z"
      responses:
        '201':
          description: Created
        '500':
          description: Unknown error

  /post/ai:
    post:
      summary: Create an AI-generated draft post
      description: Generates a post caption from a prompt and creates a draft post. Optionally attaches social profiles, brand kit context, a reusable hashtag library, and one AI-generated image.
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - prompt
              properties:
                prompt:
                  type: string
                  description: Prompt describing the post Ocoya should generate. Minimum 10 characters.
                  minLength: 10
                  example: Write a launch post for our new analytics dashboard.
                tone:
                  type: string
                  description: Caption tone for the AI draft.
                  enum: [professional, friendly, educational, bold, founder_led]
                  example: professional
                postLength:
                  type: string
                  description: Target caption length for the AI draft.
                  enum: [short, medium, long, extra_long]
                  example: medium
                socialProfileIds:
                  type: array
                  description: Connected social profile IDs that should receive the post. Get IDs from `GET /social-profiles`.
                  items:
                    type: string
                  example: [ "clh49poxf008x8kov4ncbjty9" ]
                brandId:
                  type: string
                  description: Brand kit ID used for brand context. Get IDs from `GET /brand-kits`.
                  example: cmayw38dz00047apsue9nw4tf
                hashtagLibraryId:
                  type: string
                  description: Hashtag library ID used for hashtag context. Get IDs from `GET /hashtag-libraries`.
                  example: cmayw7l5200067apsmz2tv7e8
                generateImage:
                  type: boolean
                  description: Whether to generate square image media for the AI draft.
                  example: true
                imageCount:
                  type: integer
                  description: Number of generated images when `generateImage` is `true`. Use 1 for a single image or 2-5 for a carousel.
                  minimum: 1
                  maximum: 5
                  example: 3
                referenceUrls:
                  type: array
                  description: Optional image URLs to use as visual references when `generateImage` is `true`. Ocoya uses these images for style, composition, layout, and subject guidance; they are not attached directly to the post.
                  items:
                    type: string
                  example: [ "https://example.com/reference.png" ]
                referenceDesignIds:
                  type: array
                  description: Optional Studio design IDs to use as visual references when `generateImage` is `true`. Get IDs from `GET /studio-templates`.
                  items:
                    type: string
                  example: [ "design_123" ]
      responses:
        '201':
          description: Queued. Returns immediately with status `GENERATING`; fetch the post later to see the completed draft.
        '400':
          description: Invalid request
        '500':
          description: Unknown error

  /campaigns:
    post:
      summary: Create an AI-generated campaign
      description: Queues generation for a multi-post AI campaign and returns immediately with `GENERATING` status. Campaign posts are generated asynchronously in the background.
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - prompt
              properties:
                prompt:
                  type: string
                  description: Campaign prompt or brief.
                  minLength: 3
                  example: Summer launch campaign for our ecommerce analytics dashboard.
                goal:
                  type: string
                  description: Campaign objective.
                  enum: [awareness, leads, launch, offer, education, event]
                  example: launch
                audience:
                  type: string
                  description: Primary campaign audience.
                  enum: [business_owners, founders_executives, marketing_teams, buyers_customers, local_community, investors, first_time_buyers, existing_customers]
                  example: marketing_teams
                duration:
                  type: integer
                  description: Campaign duration in days, from 1 to 30. Defaults to 7.
                  minimum: 1
                  maximum: 30
                  example: 10
                count:
                  type: integer
                  description: Number of posts to generate, from 3 to 30. Defaults to 5.
                  minimum: 3
                  maximum: 30
                  example: 6
                postLength:
                  type: string
                  description: Target caption length for each generated campaign post.
                  enum: [short, medium, long, extra_long]
                  example: medium
                tone:
                  type: string
                  description: Caption tone for campaign posts.
                  enum: [professional, friendly, educational, bold, founder_led]
                  example: professional
                brandId:
                  type: string
                  description: Brand kit ID used for brand context. When campaign media is generated, brand kit logos and icons are treated as protected reference assets. Get IDs from `GET /brand-kits`.
                  example: cmayw38dz00047apsue9nw4tf
                hashtagLibraryId:
                  type: string
                  description: Hashtag library ID used for hashtag context. Get IDs from `GET /hashtag-libraries`.
                  example: cmayw7l5200067apsmz2tv7e8
                socialProfileIds:
                  type: array
                  description: Connected social profile IDs to attach when generated campaign posts are saved. Get IDs from `GET /social-profiles`.
                  items:
                    type: string
                  example: [ "clh49poxf008x8kov4ncbjty9" ]
                generateMedia:
                  type: boolean
                  description: Whether to generate images for campaign posts.
                  example: true
                imageCount:
                  type: integer
                  description: Number of images to generate for each campaign post, from 1 to 5. Values above 1 create carousel-style post creatives. Defaults to 1.
                  minimum: 1
                  maximum: 5
                  example: 3
                referenceUrls:
                  type: array
                  description: Optional image URLs to use as visual references when `generateMedia` is `true`. Maximum 3.
                  items:
                    type: string
                  example: [ "https://example.com/reference.png" ]
                referenceDesignIds:
                  type: array
                  description: Optional Studio design IDs to use as visual references when `generateMedia` is `true`. Get IDs from `GET /studio-templates`. Maximum 3.
                  items:
                    type: string
                  example: [ "design_123" ]
      responses:
        '202':
          description: Campaign generation queued
          content:
            application/json:
              schema:
                type: object
                properties:
                  campaignId:
                    type: string
                    example: cmayxcmpn00087aps2m7hjs9z
                  status:
                    type: string
                    example: GENERATING
                  queued:
                    type: boolean
                    example: true
                  generation:
                    type: object
                    description: Campaign generation progress metadata.
        '400':
          description: Invalid request
        '500':
          description: Unknown error

  /post/{postId}:
    patch:
      summary: Update post
      description: Returns an id of the updated post
      parameters:
        - in: path
          name: postId
          required: true
          description: Ocoya post ID.
          schema:
            type: string
            example: cmajvvb9q0003ja5vh0538j6r
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                caption:
                  type: string
                  description: New caption to apply to existing post variations.
                  example: "Launching our summer campaign today."
                scheduledAt:
                  type: string
                  nullable: true
                  description: ISO 8601 datetime when the post should be scheduled, or `null` to make it unscheduled.
                  example: "2024-01-01T00:00:00Z"
                publishNow:
                  type: boolean
                  description: Publish the existing post immediately without creating a new post.
                  example: true
                brandId:
                  type: string
                  nullable: true
                  description: Brand kit ID to apply, or `null` to remove the brand kit.
                  example: "cmayw7l5200067apsmz2tv7e8"
                mediaUrls:
                  type: array
                  description: Full replacement set of publicly reachable image or video URLs. Maximum 5. Use an empty array to remove all media.
                  items:
                    type: string
                  example: [ "https://example.com/image.jpg" ]
                addMediaUrls:
                  type: array
                  description: Publicly reachable image or video URLs to add without removing existing media. Maximum 5 total.
                  items:
                    type: string
                  example: [ "https://example.com/image.jpg" ]
                clearMedia:
                  type: boolean
                  description: Remove all media from the post. Ignored when mediaUrls is provided.
                  example: false
                socialProfileIds:
                  type: array
                  description: Full replacement set of connected social profile IDs that should receive the post. Get IDs from `GET /social-profiles`.
                  items:
                    type: string
                  example: [ "clh49poxf008x8kov4ncbjty9" ]
                addSocialProfileIds:
                  type: array
                  description: Connected social profile IDs to add without removing profiles already attached to the post.
                  items:
                    type: string
                  example: [ "clh49poxf008x8kov4ncbjty9" ]
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error
    delete:
      summary: Delete post
      description: Deletes a post by Post id and cancels all schedules. Returns nothing.
      parameters:
        - in: path
          name: postId
          required: true
          description: Ocoya post ID.
          schema:
            type: string
            example: cmajvvb9q0003ja5vh0538j6r
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error

  /workflow:
    get:
      summary: List all workflows
      description: Returns information about all workflows
      parameters:
        - in: query
          name: workspaceId
          required: true
          description: Ocoya workspace ID. Get one from `GET /workspaces`.
          schema:
            type: string
            example: cmayvq3hk00017apshay5qezu
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error

  /workflow/{workflowId}:
    get:
      summary: List information about the workflow
      description: Returns information about all workflow steps
      parameters:
        - in: path
          name: workflowId
          required: true
          description: Ocoya workflow ID.
          schema:
            type: string
            example: cmajvvb9q0003ja5vh0538j6r
      responses:
        '200':
          description: Success
        '500':
          description: Unknown error
    post:
      summary: Toggle workflow on or off
      description: Enables or disables the workflow. Returns nothing.
      parameters:
        - in: path
          name: workflowId
          required: true
          description: Ocoya workflow ID.
          schema:
            type: string
            example: cmajvvb9q0003ja5vh0538j6r
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - on
              properties:
                on:
                  type: boolean
                  description: Set to `true` to enable the workflow or `false` to disable it.
                  example: true

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

security:
  - ApiKeyAuth: []
