openapi: 3.0.0
"x-mint": {
    "mcp": {
      "enabled": true
    }
  }
info:
  title: Proposals API
  version: 1.0.0
  description: |
    Endpoints for managing product proposals and their statuses.
servers:
  - url: https://marketplace-api.fabric.inc
    description: Production server
tags:
  - name: Proposals
    description: Proposal operations
security:
  - Bearer: []
paths:
  /v1/retailers/{retailer_id}/proposals/products/:
    get:
      tags:
        - Proposals
      summary: Get all product proposals
      parameters:
        - name: retailer_id
          in: path
          required: true
          description: The unique retailer ID. In the Dropship UI this is called the **Merchant ID**. To find your Merchant ID, click your merchant name in the top nav.
          schema:
            type: integer
            example: 1001
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                required:
                - count
                - results
                type: object
                properties:
                  count:
                    description: The total number of records
                    example: 100
                    type: integer
                  next:
                    description: Next page (applicable in a paginated response)
                    example: https://api.example.org/demo/{retailer_id}/?page=5
                    type: string
                    format: uri
                    nullable: true
                  previous:
                    description:
                      Previous page (applicable in a paginated response)
                    example: https://api.example.org/demo/{retailer_id}/?page=3
                    type: string
                    format: uri
                    nullable: true
                  results:
                    type: array
                    items:
                      $ref: "#/components/schemas/ProductProposal"

  /v1/retailers/{retailer_id}/proposals/{id}/:
    get:
      tags:
        - Proposals
      summary: Get a specific proposal
      parameters:
        - name: retailer_id
          in: path
          required: true
          description: The unique retailer ID. In the Dropship UI this is called the **Merchant ID**. To find your Merchant ID, click your merchant name in the top nav.
          schema:
            type: integer
            example: 1001
        - name: id
          in: path
          required: true
          description: The unique identifier of the proposal. This ID is automatically generated when a proposal is created.
          schema:
            type: integer
            example: 8008
      responses:
        '200':
          description: Proposal details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductProposal'

  /v1/retailers/{retailer_id}/proposals/{id}/approve/:
    get:
      tags:
        - Proposals
      summary: Approve a proposal
      parameters:
        - name: retailer_id
          in: path
          required: true
          description: The unique retailer ID. In the Dropship UI this is called the **Merchant ID**. To find your Merchant ID, click your merchant name in the top nav.
          schema:
            type: integer
            example: 1001
        - name: id
          in: path
          required: true
          description: The unique identifier of the proposal. This ID is automatically generated when a proposal is created.
          schema:
            type: integer
      responses:
        '200':
          description: Proposal details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductProposal'

  /v1/retailers/{retailer_id}/proposals/{id}/complete/:
    put:
      tags:
        - Proposals
      summary: Mark a proposal as complete
      parameters:
        - name: retailer_id
          in: path
          required: true
          description: The unique retailer ID. In the Dropship UI this is called the **Merchant ID**. To find your Merchant ID, click your merchant name in the top nav.
          schema:
            type: integer
            example: 1001
        - name: id
          in: path
          required: true
          description: The unique identifier of the proposal. This ID is automatically generated when a proposal is created.
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductProposalBody"
      responses:
        '200':
          description: Proposal details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductProposal'

  /v1/retailers/{retailer_id}/proposals/{id}/proposal-products/:
    get:
      tags:
        - Proposals
      summary: List proposal products by proposal ID
      parameters:
        - name: retailer_id
          in: path
          required: true
          description: The unique retailer ID. In the Dropship UI this is called the **Merchant ID**. To find your Merchant ID, click your merchant name in the top nav.
          schema:
            type: integer
            example: 1001
        - name: id
          in: path
          required: true
          description: The unique identifier of the proposal. This ID is automatically generated when a proposal is created.
          schema:
            type: integer
      responses:
        '200':
          description: Products within the proposal
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProductProposal'

  /v1/rulesets/{ruleset_id}/proposals/products/:
    get:
      tags:
        - Proposals
      summary: Retrieve proposal products associated with a ruleset.
      parameters:
        - name: ruleset_id
          description: The ruleset unique identifier. To retrieve this ID, login to Dropship and navigate to **Settings** > **Product Rulesets** and select a ruleset. The ruleset ID appears at the end of the HTTP URL.
          in: path
          required: true
          schema:
            type: integer
            example: 228
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                required:
                - count
                - results
                type: object
                properties:
                  count:
                    description: The total number of records
                    example: 100
                    type: integer
                  next:
                    description: Next page (applicable in a paginated response)
                    example: https://api.example.org/demo/{retailer_id}/?page=5
                    type: string
                    format: uri
                    nullable: true
                  previous:
                    description:
                      Previous page (applicable in a paginated response)
                    example: https://api.example.org/demo/{retailer_id}/?page=3
                    type: string
                    format: uri
                    nullable: true
                  results:
                    type: array
                    items:
                      $ref: "#/components/schemas/ProductProposal"

  /v1/rulesets/{ruleset_id}/proposals/{id}/proposal-products/:
    get:
      tags:
        - Proposals
      summary: Get a specific proposal product by ruleset
      parameters:
        - name: ruleset_id
          description: The ruleset unique identifier. To retrieve this ID, login to Dropship and navigate to **Settings** > **Product Rulesets** and select a ruleset. The ruleset ID appears at the end of the HTTP URL.
          in: path
          required: true
          schema:
            type: integer
        - name: id
          in: path
          required: true
          description: The unique identifier of the proposal.
          schema:
            type: integer
      responses:
        '200':
          description: List of products in the proposal. 
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProductProposal'

  /v1/brands/{brand_id}/connections/{id}/departments/:
    get:
      tags:
        - Proposals
      summary: Get all proposal departments
      description: A Proposal Department defines the product category for your proposal submission. Each retailer partner manages one or more Proposal Departments. You must select a Proposal Department before submitting a proposal to a partner.
      parameters:
        - name: brand_id
          in: path
          required: true
          schema:
            type: number
          description:
            The unique brand ID. In the Dropship UI this is called the **Supplier ID**. To find your Supplier ID, click your supplier name in the top nav.
          example:
            - 1249
        - name: id
          in: path
          required: true
          description: The unique connection id. This ID is automatically generated when a connection is created.
          schema:
            type: integer
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                required:
                - count
                - results
                type: object
                properties:
                  count:
                    description: The total number of records
                    example: 100
                    type: integer
                  next:
                    description: Next page (applicable in a paginated response)
                    example: https://api.example.org/demo/{retailer_id}/?page=5
                    type: string
                    format: uri
                    nullable: true
                  previous:
                    description:
                      Previous page (applicable in a paginated response)
                    example: https://api.example.org/demo/{retailer_id}/?page=3
                    type: string
                    format: uri
                    nullable: true
                  results:
                    type: array
                    items:
                      $ref: "#/components/schemas/DepartmentResponse"

  /v1/brands/{brand_id}/connections/{id}/departments/{department_id}/:
    get:
      tags:
        - Proposals
      summary: Get a specific departments details
      description: The Get Proposal Department Details endpoint provides comprehensive information for a specific proposal department. With this, you can see all associated product templates and rulesets, and easily download a sample template if one's available.
      parameters:
        - name: brand_id
          in: path
          required: true
          schema:
            type: number
          description:
            The unique brand ID. In the Dropship UI this is called the **Supplier ID**. To find your Supplier ID, click your supplier name in the top nav.
          example:
            - 1249
        - name: id
          in: path
          required: true
          description: The unique connection id. This ID is automatically generated when a connection is created.
          schema:
            type: integer
        - name: department_id
          in: path
          required: true
          description: The ID of the department. It can be retrieved from the response provided by the get `departments/` endpoint.
          schema:
            type: integer
      responses:
        '200':
          description: Proposal details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DepartmentResponse"

  /v1/rule-groups/?ruleset_id={ruleset_id}:
      get:
        tags:
          - Proposals
        summary: Get ruleset details
        description: When sending proposals to a retailer partner, rulesets define the required conditions for your product attributes. Failing to meet even one of these conditions will prevent your proposal from being submitted. Use this endpoint to review the specific details of a chosen ruleset, which will guide you in preparing your data file correctly and ensuring a successful proposal submission.
        parameters:
          - name: ruleset_id
            in: path
            required: true
            description: The unique ruleset id. The ruleset’s ID can be retrieved from the response provided by the proposal department details endpoint.
            schema:
              type: integer
        responses:
          "200":
            description: OK
            content:
              application/json:
                schema:
                  required:
                  - count
                  - results
                  type: object
                  properties:
                    count:
                      description: The total number of records
                      example: 100
                      type: integer
                    next:
                      description: Next page (applicable in a paginated response)
                      example: https://api.example.org/demo/{retailer_id}/?page=5
                      type: string
                      format: uri
                      nullable: true
                    previous:
                      description:
                        Previous page (applicable in a paginated response)
                      example: https://api.example.org/demo/{retailer_id}/?page=3
                      type: string
                      format: uri
                      nullable: true
                    results:
                      type: array
                      items:
                        $ref: "#/components/schemas/RulesetResults"

  /v1/brands/{brand_id}/proposals/:
    post:
      tags:
        - Proposals
      summary: Create a Proposal
      description: Use the create proposal endpoint to initiate a new, empty draft proposal. This draft will subsequently be enriched with your product data once the file is received
      parameters:
        - name: brand_id
          in: path
          required: true
          schema:
            type: number
          description:
            The unique brand ID. In the Dropship UI this is called the **Supplier ID**. To find your Supplier ID, click your supplier name in the top nav.
          example:
            - 1249
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductProposalBody"
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductProposal"

  /v1/brands/{brand_id}/proposals/{id}/apply-transformer/:
    post:
      tags:
        - Proposals
      summary: Apply a transformer to a proposal
      description: This endpoint allows you to apply a specified transformer to an existing draft proposal. This process modifies and restructures the proposal's data, ensuring it meets specific formatting or processing requirements.
      parameters:
        - name: brand_id
          in: path
          required: true
          schema:
            type: number
          description:
            The unique brand ID. In the Dropship UI this is called the **Supplier ID**. To find your Supplier ID, click your supplier name in the top nav.
          example:
            - 1249
        - name: id
          in: path
          required: true
          description: The unique proposal id. This ID is automatically generated when a proposal is created.
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductProposalBody"
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductProposal"

  /v1/brands/{brand_id}/proposals/{id}/approve/:
    get:
      tags:
        - Proposals
      summary: Get an approved proposal
      parameters:
        - name: brand_id
          in: path
          required: true
          schema:
            type: number
          description:
            The unique brand ID. In the Dropship UI this is called the **Supplier ID**. To find your Supplier ID, click your supplier name in the top nav.
          example:
            - 1249
        - name: id
          in: path
          required: true
          description: The unique proposal id. This ID is automatically generated when a proposal is created.
          schema:
            type: integer
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductProposal"

  /v1/brands/{brand_id}/proposals/{id}/compatibility-rulesets-failure-reports/:
    get:
      tags:
        - Proposals
      summary: Get a rulesets failure reports
      description: To view a report of failed compatibility rulesets, use the Get Compatibility Rulesets Failure Report endpoint. The returned `id` allows you to then call the Get Job Detail endpoint for in-depth `ruleset_failure_report` and `ruleset_error_report` details.
      parameters:
        - name: brand_id
          in: path
          required: true
          schema:
            type: number
          description:
            The unique brand ID. In the Dropship UI this is called the **Supplier ID**. To find your Supplier ID, click your supplier name in the top nav.
          example:
            - 1249
        - name: id
          in: path
          required: true
          description: The unique proposal id. This ID is automatically generated when a proposal is created.
          schema:
            type: integer
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JobDetail"

  /v1/brands/{brand_id}/proposals/{id}/rulesets-failure-summary/:
    get:
      tags:
        - Proposals
      summary: Get a rulesets failure summary
      parameters:
        - name: brand_id
          in: path
          required: true
          schema:
            type: number
          description:
            The unique brand ID. In the Dropship UI this is called the **Supplier ID**. To find your Supplier ID, click your supplier name in the top nav.
          example:
            - 1249
        - name: id
          in: path
          required: true
          description: The unique proposal id. This ID is automatically generated when a proposal is created.
          schema:
            type: integer
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductProposal"

  /v1/brands/{brand_id}/proposals/{id}/rulesets-attributes-summary/:
    get:
      tags:
        - Proposals
      summary: Get a rulesets attribute summary
      parameters:
        - name: brand_id
          in: path
          required: true
          schema:
            type: number
          description:
            The unique brand ID. In the Dropship UI this is called the **Supplier ID**. To find your Supplier ID, click your supplier name in the top nav.
          example:
            - 1249
        - name: id
          in: path
          required: true
          description: The unique proposal id. This ID is automatically generated when a proposal is created.
          schema:
            type: integer
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductProposal"

components:
  schemas:
    BrandRuleset:
      type: object
      description: Details about the brand ruleset applied to this feed.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the brand ruleset.
          example: 36
    DepartmentResponse:
      type: object
      description: Represents a product feed configuration for a retailer, including associated users, templates, and rulesets.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the feed.
          example: 1418
        retailer:
          $ref: "#/components/schemas/Retailer"
        owner_user:
          $ref: "#/components/schemas/OwnerUser"
        manager_user:
          type: object
          nullable: true
          description: Details about the manager user, if any.
          example: null
        name:
          type: string
          description: The name of the feed.
          example: fabric Merchant Apparel
        code:
          type: string
          description: A unique code for the feed.
          example: fabric-merchant-general
        sample_template_url:
          type: string
          format: url
          nullable: true
          description: URL to a sample template for this feed.
          example: https://res.cloudinary.com/revcascade/raw/upload/v1658950690/sample-templates/ApparelBad.csv
        description:
          type: string
          nullable: true
          description: A description of the feed.
          example: null
        template:
          $ref: "#/components/schemas/Template"
        brand_ruleset:
          $ref: "#/components/schemas/BrandRuleset"
        retailer_ruleset:
          $ref: "#/components/schemas/RetailerRuleset"
        is_active:
          type: boolean
          description: Indicates if the feed is active.
          example: true
    JobDetail:
      type: object
      description: Represents the details of a background job or process, including its status, associated objects, and any generated reports.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier for the job.
          example: 1762791
        content_type:
          type: integer
          description: An identifier for the type of content or operation the job relates to.
          example: 9
        object_id:
          type: integer
          format: int64
          description: The ID of the primary object associated with this job (e.g., a proposal or connection ID).
          example: 1298
        connection:
          type: object # Or specific properties if it's an object when not null
          nullable: true
          description: Details of the connection related to this job, if any.
          example: null
        runtime_id:
          type: string
          format: uuid
          description: A unique identifier for the specific execution instance of the job.
          example: 3af6d254-066d-4a19-9f44-78d7f9ed28a2
        module_name:
          type: string
          description: The name of the module or function that executed this job.
          example: create_compatibility_rulesets_failure_report
        created_at:
          type: string
          format: date-time
          description: The timestamp when the job record was created.
          example: 2023-12-07T23:14:23Z
        start_time:
          type: string
          format: date-time
          nullable: true
          description: The timestamp when the job started execution.
          example: null
        finish_time:
          type: string
          format: date-time
          nullable: true
          description: The timestamp when the job finished execution.
          example: null
        description:
          type: string
          nullable: true
          description: A human-readable description of the job.
          example: null
        total_success:
          type: integer
          nullable: true
          description: The total count of successful operations within the job.
          example: null
        total_failure:
          type: integer
          nullable: true
          description: The total count of failed operations within the job.
          example: null
        metadata:
            $ref: '#/components/schemas/MetadataItem'
        error_count:
          type: integer
          description: The number of errors encountered during the job's execution.
          example: 0
        error_logs:
          type: array
          description: A list of detailed error logs generated by the job.
          items:
            type: object # Or a $ref to an ErrorLogItem schema if defined
          example: []
    MetadataItem:
      type: object
      description: Represents a single metadata entry, often linking to external reports or files.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier for this metadata entry.
          example: 17331237
        content_type:
          type: integer
          description: An identifier for the type of content this metadata relates to.
          example: 124
        object_id:
          type: integer
          format: int64
          description: The ID of the object this metadata is associated with (e.g., a job ID or proposal ID).
          example: 1762791
        type:
          type: string
          description: The data type of the 'value' field, indicating what kind of data is stored.
          example: string
        name:
          type: string
          description: A descriptive name for this metadata entry (e.g., "ruleset_failure_report").
          example: ruleset_failure_report
        value:
          type: string
          format: uri
          description: The actual value of the metadata, often a URL to a resource.
          example: https://assets-staging.revcascade.com/temp_files/5d88c779-9bc5-4401-9073-024b106fe00a/Ruleset_Failure_Report_20231207_231424.csv
        created_at:
          type: string
          format: date-time
          description: The timestamp when this metadata entry was created.
          example: 2023-12-07T23:14:24Z
    OwnerUser:
      type: object
      description: Details about the user who owns this feed.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the user.
          example: 1002
        first_name:
          type: string
          description: The first name of the user.
          example: Kyle
        last_name:
          type: string
          description: The last name of the user.
          example: Stainer
        title:
          type: string
          description: The title or role of the user.
          example: Engineering
        status:
          type: string
          description: The current status of the user (e.g., 'active').
          example: active
        type:
          type: string
          description: The type of user (e.g., 'standard').
          example: standard
        photo_url:
          type: string
          format: url
          description: URL to the user's photo.
          example: https://images.revcascade.com/users/2c5346e8b01f40de8977d29ee038f995/photo.jpg
        profile_photo:
          type: string
          format: url
          description: URL to the user's profile photo.
          example: https://images.revcascade.com/users/2c5346e8b01f40de8977d29ee038f995/photo.jpg
        is_me:
          type: boolean
          description: Indicates if the user is the current authenticated user.
          example: false
    ProductProposal:
      type: object
      properties:
        id:
          type: integer
          title: ID
          readOnly: true
          description: Unique identifier for the proposal. This ID is automatically generated when a proposal is created.
          example: 101
        name:
          type: string
          title: Name
          maxLength: 128
          minLength: 1
          description: Name of the proposal.
          example: "Winter 2025 Collection Update"
        status:
          type: string
          title: Status
          enum: [draft, proposed, revised, completed, approved, declined, archived, pricing_approved, reopened, withdrawn]
          description: Current status of the proposal.
          example: "proposed"
        source:
          type: string
          title: Source
          enum: [console, merchandising]
          description: The origin of the proposal.
          example: "console"
        proposal_type:
          type: string
          title: Proposal type
          enum: [new_product, cost_update, image_update, attribute_update, legacy]
          description: Type of proposal indicating its purpose.
          example: "new_product"
        recipient:
          type: string
          title: Recipient
          readOnly: true
          description: Recipient of the proposal.
          example: "retailer_456"
        sender:
          type: string
          title: Sender
          readOnly: true
          description: Sender who created the proposal.
          example: "supplier_123"
        memos:
          type: string
          title: Memos
          readOnly: true
          description: Internal notes or memos associated with the proposal.
          example: "Initial draft submitted by merchandising team."
        created_by:
          type: string
          title: Created by
          readOnly: true
          description: User or system that created the proposal.
          example: "user_789"
        connection:
          type: string
          title: Connection
          readOnly: true
          description: Integration or channel connection identifier.
          example: "integration_abc"
        retailer:
          type: string
          title: Retailer
          readOnly: true
          description: Retailer associated with the proposal.
          example: "Fashion Retail Co."
        brand:
          type: string
          title: Brand
          readOnly: true
          description: Brand associated with the products in the proposal.
          example: "FrostWear"
        department:
          type: string
          title: Department
          readOnly: true
          description: Department to which the proposal belongs.
          example: "Apparel"
        return_reason:
          type: string
          title: Return reason
          readOnly: true
          description: Reason the proposal was returned for revisions.
          example: "Insufficient pricing justification"
        return_reason_detail:
          type: string
          title: Return reason detail
          nullable: true
          description: Additional details explaining the return reason.
          example: "Missing supplier cost comparison documentation."
        products:
          type: string
          title: Products
          readOnly: true
          description: Products included in the proposal.
          example: "[{ product_id: 202, name: 'Arctic Parka' }]"
        push_to_shopify:
          type: boolean
          title: Push to Shopify
          description: Indicates whether the proposal should be pushed to Shopify.
          example: true
        shopify_template:
          type: string
          title: Shopify template
          readOnly: true
          description: Shopify-specific template used.
          example: "default_fashion_template"
        export_platform_template:
          type: string
          title: Export platform template
          readOnly: true
          description: Template used for exporting to external platforms.
          example: "standard_export_v1"
        attachments:
          type: string
          title: Attachments
          readOnly: true
          description: Attached files or resources for the proposal.
          example: "[{ filename: 'lookbook.pdf' }]"
        end_at:
          type: string
          format: date-time
          title: End at
          nullable: true
          description: Optional end date for the proposal's active status.
          example: "2025-09-30T23:59:59Z"
        issues_summary:
          type: string
          title: Issues summary
          readOnly: true
          description: Summary of identified issues within the proposal.
          example: "Missing product images for 3 items"
        is_acknowledged:
          type: boolean
          title: Is acknowledged
          readOnly: true
          description: Indicates whether the proposal has been acknowledged.
          example: false
        item_approved_count:
          type: integer
          title: Item approved count
          readOnly: true
          description: Number of approved items in the proposal.
          example: 5
        item_deleted_count:
          type: integer
          title: Item deleted count
          readOnly: true
          description: Number of deleted items in the proposal.
          example: 0
        item_rejected_count:
          type: integer
          title: Item rejected count
          readOnly: true
          description: Number of rejected items in the proposal.
          example: 1
        item_skipped_count:
          type: integer
          title: Item skipped count
          readOnly: true
          minimum: -2147483648
          maximum: 2147483647
          description: Number of items skipped during processing.
          example: 2
        item_count:
          type: string
          title: Item count
          readOnly: true
          description: Total number of items in the proposal.
          example: "10"
        item_classified_count:
          type: string
          title: Item classified count
          readOnly: true
          description: Number of items that have been classified.
          example: "8"
        item_ready_count:
          type: string
          title: Item ready count
          readOnly: true
          description: Number of items ready for final review or processing.
          example: "6"
        item_failed_count:
          type: string
          title: Item failed count
          readOnly: true
          description: Number of items that failed validation or processing.
          example: "1"
        action_required:
          type: string
          title: Action required
          readOnly: true
          description: Description of action required from the user.
          example: "Upload missing product photos"
        has_action:
          type: string
          title: Has action
          readOnly: true
          description: Indicates whether there is a pending action.
          example: "yes"
        has_revision:
          type: string
          title: Has revision
          readOnly: true
          description: Flag indicating whether the proposal includes revisions.
          example: "true"
        has_unresolved_issues:
          type: boolean
          title: Has unresolved issues
          readOnly: true
          description: Indicates if the proposal still has unresolved issues.
          example: true
        has_price_changes:
          type: boolean
          title: Has price changes
          description: Indicates if there are pricing updates in the proposal.
          example: true
        collaborators:
          type: string
          title: Collaborators
          readOnly: true
          description: Users collaborating on the proposal.
          example: "user_789, user_321"
        target_live_date:
          type: string
          format: date-time
          title: Target live date
          nullable: true
          description: Intended go-live date for the proposed changes.
          example: "2025-10-01T00:00:00Z"
        start_at:
          type: string
          format: date-time
          title: Start at
          nullable: true
          description: Start date of the proposal.
          example: "2025-04-01T00:00:00Z"
        expires_at:
          type: string
          format: date-time
          title: Expires at
          nullable: true
          description: Expiration date of the proposal.
          example: "2025-06-01T00:00:00Z"
        updated_at:
          type: string
          format: date-time
          title: Updated at
          readOnly: true
          description: Timestamp when the proposal was last updated.
          example: "2025-04-22T15:30:00Z"
        created_at:
          type: string
          format: date-time
          title: Created at
          readOnly: true
          description: Timestamp when the proposal was created.
          example: "2025-04-20T08:45:00Z"
        draft_proposed_at:
          type: string
          format: date-time
          title: Draft proposed at
          nullable: true
          description: Timestamp when the draft was proposed.
          example: "2025-04-10T12:00:00Z"
        acknowledged_at:
          type: string
          format: date-time
          title: Acknowledged at
          nullable: true
          description: Timestamp when the proposal was acknowledged.
          example: "2025-04-15T09:30:00Z"
        proposed_at:
          type: string
          format: date-time
          title: Proposed at
          nullable: true
          description: Timestamp when the proposal was officially proposed.
          example: "2025-04-20T10:00:00Z"
        archived_at:
          type: string
          format: date-time
          title: Archived at
          nullable: true
          description: Timestamp when the proposal was archived.
          example: "2025-04-22T17:00:00Z"
        revised_at:
          type: string
          format: date-time
          title: Revised at
          nullable: true
          description: Timestamp when the proposal was last revised.
          example: "2025-04-21T14:15:00Z"
        approved_at:
          type: string
          format: date-time
          title: Approved at
          nullable: true
          description: Timestamp when the proposal was approved.
          example: "2025-04-25T11:00:00Z"
        declined_at:
          type: string
          format: date-time
          title: Declined at
          nullable: true
          description: Timestamp when the proposal was declined.
          example: "2025-04-26T10:30:00Z"
        pricing_approved_at:
          type: string
          format: date-time
          title: Pricing approved at
          nullable: true
          description: Timestamp when pricing was approved.
          example: "2025-04-24T13:45:00Z"
        completed_at:
          type: string
          format: date-time
          title: Completed at
          nullable: true
          description: Timestamp when the proposal was completed.
          example: "2025-04-28T16:00:00Z"
        withdrawn_at:
          type: string
          format: date-time
          title: Withdrawn at
          nullable: true
          description: Timestamp when the proposal was withdrawn.
          example: "2025-04-27T08:00:00Z"
        withdraw_reason:
          type: string
          title: Withdraw reason
          maxLength: 300
          nullable: true
          description: Reason why the proposal was withdrawn.
          example: "The product line was discontinued by the supplier."
        tags:
          type: string
          title: Tags
          readOnly: true
          description: Metadata tags for classification or filtering.
          example: "seasonal,featured,high-priority"
      required:
        - name
    ProductProposalBody:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          title: Name
          description: The title or label of the product proposal.
          minLength: 1
          maxLength: 128
          example: "Eco-Friendly Tumbler Set"
        status:
          type: string
          title: Status
          description: Current state of the proposal in the lifecycle.
          enum:
            - draft
            - proposed
            - revised
            - completed
            - approved
            - declined
            - archived
            - pricing_approved
            - reopened
            - withdrawn
          example: "draft"
        source:
          type: string
          title: Source
          description: Indicates where the proposal originated from.
          enum:
            - console
            - merchandising
          example: "console"
        proposal_type:
          type: string
          title: Proposal type
          description: The category of the proposal.
          enum:
            - new_product
            - cost_update
            - image_update
            - attribute_update
            - legacy
          example: "new_product"
        return_reason_detail:
          type: string
          title: Return reason detail
          description: Detailed explanation of the return reason.
          nullable: true
          example: "Incorrect pricing on listed item."
        push_to_shopify:
          type: boolean
          title: Push to Shopify
          description: Indicates whether the proposal should be pushed to Shopify.
          example: true
        end_at:
          type: string
          format: date-time
          title: End at
          description: The date and time when the proposal ends.
          nullable: true
          example: "2025-06-30T23:59:59Z"
        item_skipped_count:
          type: integer
          title: Item skipped count
          description: Number of items that were skipped during processing.
          minimum: -2147483648
          maximum: 2147483647
          example: 3
        has_price_changes:
          type: boolean
          title: Has price changes
          description: Indicates if any items have price changes.
          example: false
        target_live_date:
          type: string
          format: date-time
          title: Target live date
          description: Scheduled date for the proposal to go live.
          nullable: true
          example: "2025-07-01T00:00:00Z"
        start_at:
          type: string
          format: date-time
          title: Start at
          description: Date and time when the proposal becomes active.
          nullable: true
          example: "2025-05-01T00:00:00Z"
        expires_at:
          type: string
          format: date-time
          title: Expires at
          description: Date and time when the proposal expires.
          nullable: true
          example: "2025-07-31T23:59:59Z"
        draft_proposed_at:
          type: string
          format: date-time
          title: Draft proposed at
          description: When the draft was submitted as a proposal.
          nullable: true
          example: "2025-04-20T12:00:00Z"
        acknowledged_at:
          type: string
          format: date-time
          title: Acknowledged at
          description: When the proposal was acknowledged.
          nullable: true
          example: "2025-04-22T09:00:00Z"
        proposed_at:
          type: string
          format: date-time
          title: Proposed at
          description: When the proposal was formally proposed.
          nullable: true
          example: "2025-04-23T10:00:00Z"
        archived_at:
          type: string
          format: date-time
          title: Archived at
          description: When the proposal was archived.
          nullable: true
          example: "2025-08-01T10:00:00Z"
        revised_at:
          type: string
          format: date-time
          title: Revised at
          description: When the proposal was revised.
          nullable: true
          example: "2025-04-25T15:00:00Z"
        approved_at:
          type: string
          format: date-time
          title: Approved at
          description: When the proposal received approval.
          nullable: true
          example: "2025-05-01T10:00:00Z"
        declined_at:
          type: string
          format: date-time
          title: Declined at
          description: When the proposal was declined.
          nullable: true
          example: "2025-05-02T12:00:00Z"
        pricing_approved_at:
          type: string
          format: date-time
          title: Pricing approved at
          description: When pricing for the proposal was approved.
          nullable: true
          example: "2025-05-03T14:00:00Z"
        completed_at:
          type: string
          format: date-time
          title: Completed at
          description: When the proposal was marked as completed.
          nullable: true
          example: "2025-05-05T16:00:00Z"
        withdrawn_at:
          type: string
          format: date-time
          title: Withdrawn at
          description: When the proposal was withdrawn.
          nullable: true
          example: "2025-05-06T09:30:00Z"
        withdraw_reason:
          type: string
          title: Withdraw reason
          description: Reason for withdrawal of the proposal.
          maxLength: 300
          nullable: true
          example: "Vendor no longer supports product line."
    Retailer:
      type: object
      description: Details about the associated retailer.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the retailer.
          example: 1233
        name:
          type: string
          description: The name of the retailer.
          example: fabric Merchant
        code:
          type: string
          description: A unique code for the retailer.
          example: fabric-merchant
        logo_url:
          type: string
          format: url
          description: URL to the retailer's logo.
          example: https://assets.revcascade.com/retailers/d8b42096-5e46-41e4-bde0-80c17d3d3a52
        cover_url:
          type: string
          format: url
          description: URL to the retailer's cover image.
          example: https://images.revcascade.com/retailers/defaults/cover.png
        profile_tile_url:
          type: string
          format: url
          description: URL to the retailer's profile tile image.
          example: https://images.revcascade.com/retailers/defaults/profile-tile.png
        joined_at:
          type: string
          format: date-time
          description: Timestamp when the retailer joined.
          example: 2022-05-27T03:07:59Z
        is_3pm:
          type: boolean
          description: Indicates if the retailer is a 3PM (Third-Party Merchant).
          example: false
        is_rcn_retailer:
          type: boolean
          description: Indicates if the retailer is an RCN (RevCascade Network) retailer.
          example: false
        is_onboarded:
          type: boolean
          description: Indicates if the retailer has completed onboarding.
          example: true
        platform:
          type: string
          description: The platform the retailer uses.
          example: fabric
        requires_subscription:
          type: string
          description: Indicates if the retailer requires a subscription (e.g., 'disabled').
          example: disabled
        brand_permit_creation_allowed:
          type: boolean
          description: Indicates if brand permit creation is allowed for this retailer.
          example: true
        website:
          type: string
          format: url
          description: The retailer's website URL.
          example: https://www.fabric.inc
        status:
          type: string
          description: The current status of the retailer (e.g., 'active').
          example: active
        indexing_template_id:
          type: integer
          format: int64
          nullable: true
          description: The ID of the indexing template, if any.
          example: null
    RetailerRuleset:
      type: object
      description: Details about the retailer ruleset applied to this feed.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the retailer ruleset.
          example: 37
    Rule:
      type: object
      description: Defines a specific validation or processing rule within a ruleset.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the rule.
          example: 574
        name:
          type: string
          description: The name of the rule.
          example: SKU
        description:
          type: string
          description: A brief description of what the rule does.
          example: ""
        attribute:
          $ref: "#/components/schemas/RulesetAttribute"
        target:
          # Assuming target can be null based on the example, but if it can be an object
          # with specific properties, you'd define those here.
          type: object
          nullable: true
          description: Specifies the target of the rule, if any.
          example: null
        is_required:
          type: boolean
          description: Indicates if this rule is mandatory.
          example: true
        position:
          type: integer
          description: The order or priority of the rule within its group.
          example: 0
        rule_group_id:
          type: integer
          format: int64
          description: The ID of the rule group this rule belongs to.
          example: 124
        rule_validators:
          type: array
          description: A list of validators associated with this rule.
          items:
            type: object # Or a $ref to a specific RuleValidator schema if defined
          example: []
        rule_conditions:
          type: array
          description: A list of conditions that trigger or modify this rule.
          items:
            type: object # Or a $ref to a specific RuleCondition schema if defined
          example: []
        created_at:
          type: string
          format: date-time
          description: The timestamp when the rule was created.
          example: 2022-06-16T18:08:42Z
        updated_at:
          type: string
          format: date-time
          description: The timestamp when the rule was last updated.
          example: 2022-06-16T18:08:42Z
    RulesetAttribute:
      type: object
      description: Represents a product attribute, detailing its properties, type, and editing capabilities.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the attribute.
          example: 2
        code:
          type: string
          description: A unique code for the attribute.
          example: identifier
        name:
          type: string
          description: The display name of the attribute.
          example: SKU
        grouping:
          type: string
          description: The category or grouping the attribute belongs to.
          example: identifiers
        priority:
          type: integer
          description: The priority order of the attribute.
          example: 100
        description:
          type: string
          description: A detailed description of the attribute.
          example: Product SKU or Identifier
        editable_by:
          type: string
          description: Specifies who can edit the attribute (e.g., 'any', 'admin').
          example: any
        type:
          type: string
          description: The data type of the attribute (e.g., 'string', 'integer', 'boolean').
          example: string
        units:
          type: string
          description: The unit of measurement for the attribute, if applicable.
          example: ""
        default_unit:
          type: string
          nullable: true
          description: The default unit of measurement, if any.
          example: null
        available_units:
          type: array
          description: A list of available units for the attribute.
          items:
            type: string
          example: []
        is_bulk_editable:
          type: boolean
          description: Indicates if the attribute can be edited in bulk.
          example: false
    Ruleset:
      type: object
      description: Details about a specific ruleset, including its name, description, and timestamps.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the ruleset.
          example: 36
        name:
          type: string
          description: The name of the ruleset.
          example: fabric Merchant Ruleset
        description:
          type: string
          description: A brief description of the ruleset.
          example: "the default fabric merchant ruleset"
        created_at:
          type: string
          format: date-time
          description: The timestamp when the ruleset was created.
          example: 2022-06-16T18:08:08Z
        updated_at:
          type: string
          format: date-time
          description: The timestamp when the ruleset was last updated.
          example: 2022-08-24T05:38:42Z
    RulesetResults:
      type: object
      description: Defines a specific validation or processing rule within a ruleset.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the rule.
          example: 574
        name:
          type: string
          description: The name of the rule.
          example: SKU
        ruleset:
          $ref: "#/components/schemas/Ruleset"
        description:
          type: string
          description: A brief description of what the rule does.
          example: ""
        target:
          # Assuming target can be null based on example, but if it can be an object
          # with specific properties, you'd define those here.
          type: object
          nullable: true
          description: Specifies the target of the rule, if any.
          example: null
        is_required:
          type: boolean
          description: Indicates if this rule is mandatory.
          example: true
        position:
          type: integer
          description: The order or priority of the rule within its group.
          example: 0
        rules:
          $ref: "#/components/schemas/Rule"
        created_at:
          type: string
          format: date-time
          description: The timestamp when the ruleset was created.
          example: 2022-06-16T18:08:42Z
        updated_at:
          type: string
          format: date-time
          description: The timestamp when the ruleset was last updated.
          example: 2022-06-16T18:08:42Z
    Template:
      type: object
      description: Details about the template used for this feed.
      properties:
        id:
          type: integer
          format: int64
          description: The unique identifier of the template.
          example: 3245
        name:
          type: string
          description: The name of the template.
          example: fabric General Merchandise
        code:
          type: string
          description: The code of the template.
          example: fabric-general-merchandise
  securitySchemes:
    Bearer:
      type: http
      scheme: bearer