openapi: 3.0.3
info:
  title: PressMatrix Import API
  version: '2.0'
  description: |
    Automates import of periodicals as PDFs or EPUBs for the PressMatrix Kiosk.

servers:
  - url: https://pegasus.pressmatrix.com/api/v2/importer

security:
  - TokenAuth: []

components:
  securitySchemes:
    TokenAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'Token-based authentication. Example: "Authorization: Token {TOKEN_GENERATED_BY_PMX}"'

  schemas:

    EmagImportAttributes:
      type: object
      description: Attributes for PDF-based import. Required if using PDF import.
      properties:
        import_attributes:
          type: object
          required: [pdf_location]
          properties:
            import_images:
              type: boolean
              description: Extract and import images as widgets from the PDF.
            pdf_location:
              type: string
              format: uri
              description: URL to the PDF file (HTTPS, valid certificate required).
            xml_location:
              type: string
              format: uri
              description: URL to XML file for custom widget mapping (HTTPS, valid certificate required).
    PlannedEmagImportAttributes:
      type: object
      description: Attributes for Planned PDF import. Required if using Planned PDF import.
      properties:
        import_attributes:
          type: object
          required: [pdf_location]
          properties:
            import_images:
              type: boolean
              description: Extract and import images from the PDF.
            pdf_location:
              type: string
              format: uri
              description: URL to the PDF file (HTTPS, valid certificate required).


    EmagEpubImportAttributes:
      type: object
      description: Attributes for EPUB-based import. Required if using EPUB import.
      properties:
        epub_import_attributes:
          type: object
          required: [pdf_location, epub_location]
          properties:
            import_articles:
              type: boolean
              description: Extract and import single articles from the feed; articles are always imported based on EPUB.
            import_images:
              type: boolean
              description: Extract and import images as widgets from the EPUB.
            pdf_location:
              type: string
              format: uri
              description: URL to PDF file associated with the EPUB (HTTPS, valid certificate required).
            epub_location:
              type: string
              format: uri
              description: URL to EPUB file to import (HTTPS, valid certificate required).

    EmagPOST:
      type: object
      required: [name, released_at]
      properties:
        name:
          type: string
          description: Name of the issue. Must be unique within the publication.
        released_at:
          type: string
          description: Date and time from which the issue is visible (YYYY-MM-DD HH:MM:SS).
        pe_id:
          type: string
          description: Planned edition identifier. Provided by PressMatrix for planned imports.
        preview:
          type: string
          description: This is a short description of the contents of this particular issue. It is visible to end users within the PressMatrix Kiosk on the issue details screen.
        apple_product_identifier:
          type: string
          pattern: '^[A-Za-z0-9_.-]+$'
          description: Identifier for Apple App Store (must be unique within the publication). Required for paid issues.
        google_product_id:
          type: string
        external_id:
          type: string
        hide_preview_widgets:
          type: boolean
        single_purchase_required:
          type: boolean
        for_subscribers_only:
          type: boolean
        cents:
          type: integer
          minimum: 0
        currency:
          type: string
          minLength: 3
          maxLength: 3
          description: this is the currency of the price defined in the cents parameter. The default currency is Euros (EUR). This is used only for paid issues only and if the issue is free, then the value should be the default EUR.
        category_ids:
          type: array
          items:
            type: integer
        text_mode_enabled:
          type: boolean
          description: Indicator whether the text mode should be active for the issue. This setting can be changed later in Pegasus also after the import phase. Important - the issue's text will be imported regardless this setting, the setting affect only the text widget availability in the app for this issue.
        language:
          type: string
          minLength: 2
          maxLength: 2
      oneOf:
        - title: "PDF import"
          description: "Standard PDF import (no pe_id)."
          allOf:
            - $ref: '#/components/schemas/EmagImportAttributes'
            - type: object
              required: [import_attributes]
              not: { required: [pe_id] }
        - title: "Planned PDF import"
          description: "Link to a planned issue via pe_id."
          allOf:
            - $ref: '#/components/schemas/PlannedEmagImportAttributes'
            - type: object
              required: [import_attributes, pe_id]
        - title: "EPUB import"
          description: "EPUB-based import."
          allOf:
            - $ref: '#/components/schemas/EmagEpubImportAttributes'
            - type: object
              required: [epub_import_attributes]

    EmagPUT:
      type: object
      properties:
        name:
          type: string
        released_at:
          type: string
        preview:
          type: string
          description: This is a short description of the contents of this particular issue. It is visible to end users within the PressMatrix Kiosk on the issue details screen.
        apple_product_identifier:
          type: string
          pattern: '^[A-Za-z0-9_.-]+$'
        google_product_id:
          type: string
        external_id:
          type: string
        hide_preview_widgets:
          type: boolean
        single_purchase_required:
          type: boolean
        for_subscribers_only:
          type: boolean
        cents:
          type: integer
          minimum: 0
        currency:
          type: string
          minLength: 3
          maxLength: 3
          description: this is the currency of the price defined in the cents parameter. The default currency is Euros (EUR). This is used only for paid issues only and if the issue is free, then the value should be the default EUR.
        category_ids:
          type: array
          items:
            type: integer
        text_mode_enabled:
          type: boolean
        language:
          type: string
          minLength: 2
          maxLength: 2
      allOf:
        - $ref: '#/components/schemas/EmagImportAttributes'
        - $ref: '#/components/schemas/EmagEpubImportAttributes'

    EmagRequestPOST:
      type: object
      required: [emag]
      properties:
        emag:
          $ref: '#/components/schemas/EmagPOST'

    EmagRequestPUT:
      type: object
      required: [emag]
      properties:
        emag:
          $ref: '#/components/schemas/EmagPUT'

    EmagSuccessResponse:
      type: object
      properties:
        id:
          type: integer
        created_at:
          type: string
          format: date-time

    ErrorResponse:
      type: object
      additionalProperties:
        type: array
        items:
          type: string
      description: Field-wise error messages (see examples).

paths:
  /organizations/{organization_id}/publications/{publication_id}/emags:
    post:
      summary: Import new periodical (emag)
      operationId: createEmag
      tags: [PDF Import]
      security:
        - TokenAuth: []
      parameters:
        - name: organization_id
          in: path
          required: true
          schema:
            type: string
        - name: publication_id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmagRequestPOST'
            examples:
              pdf:
                summary: Create emag using PDF import
                value:
                  emag:
                    name: "name of the issue"
                    released_at: "2025-07-09 10:00:00"
                    preview: "Short description for kiosk details."
                    apple_product_identifier: "com.example.kiosk.issue_2025_07"
                    google_product_id: "com.example.kiosk.issue_2025_07"
                    external_id: "ISSUE-2025-07"
                    hide_preview_widgets: false
                    single_purchase_required: false
                    for_subscribers_only: false
                    cents: 199
                    currency: "EUR"
                    category_ids: [508]
                    text_mode_enabled: true
                    language: "de"
                    import_attributes:
                      import_images: true
                      pdf_location: "https://www.mydomain.com/issue.pdf"
                      xml_location: "https://www.mydomain.com/issue.xml"
              planned_pdf:
                summary: Create planned emag using PDF import
                value:
                  emag:
                    name: "name of the issue"
                    released_at: "2025-07-09 10:00:00"
                    pe_id: "ABC_20260804"
                    preview: "Short description for kiosk details."
                    apple_product_identifier: "com.example.kiosk.issue_2025_07"
                    google_product_id: "com.example.kiosk.issue_2025_07"
                    external_id: "ISSUE-2025-07"
                    hide_preview_widgets: false
                    single_purchase_required: false
                    for_subscribers_only: false
                    cents: 199
                    currency: "EUR"
                    category_ids: [508]
                    language: "de"
                    import_attributes:
                      import_images: true
                      pdf_location: "https://www.mydomain.com/issue.pdf"
              epub:
                summary: Create emag using EPUB import
                value:
                  emag:
                    name: "EPUB Issue July 2025"
                    released_at: "2025-07-09 10:00:00"
                    preview: "EPUB-based import."
                    apple_product_identifier: "com.example.kiosk.issue_2025_07_epub"
                    google_product_id: "com.example.kiosk.issue_2025_07_epub"
                    external_id: "ISSUE-2025-07-EPUB"
                    cents: 199
                    currency: "EUR"
                    category_ids: [508, 777]
                    text_mode_enabled: true
                    language: "de"
                    epub_import_attributes:
                      import_articles: true
                      import_images: true
                      pdf_location: "https://cdn.example.com/issues/2025_07/issue.pdf"
                      epub_location: "https://cdn.example.com/issues/2025_07/issue.epub"
      responses:
        '200':
          description: Created emag
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmagSuccessResponse'
              example:
                id: 12345
                created_at: "2025-07-24T12:02:58.000Z"
        '400':
          description: Validation errors
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                field_name: ["error message"]
        '401':
          description: Unauthorized (missing/invalid token)
        '422':
          description: Unprocessable Entity (e.g. duplicate name)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                name: ["has already been taken"]
                pe_id: ["is not valid"]
        '500':
          description: Internal server error

  /organizations/{organization_id}/publications/{publication_id}/emags/{emag_id}:
    put:
      summary: Update existing periodical (emag)
      operationId: updateEmag
      tags: [PDF Import]
      security:
        - TokenAuth: []
      parameters:
        - name: organization_id
          in: path
          required: true
          schema:
            type: string
        - name: publication_id
          in: path
          required: true
          schema:
            type: string
        - name: emag_id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmagRequestPUT'
            examples:
              updateMetaOnly:
                summary: Update only meta fields
                value:
                  emag:
                    name: "Updated Issue Title – July 2025"
                    released_at: "2025-07-10 12:00:00"
                    preview: "Updated short description for kiosk details."
                    apple_product_identifier: "com.example.kiosk.issue_2025_07"
                    google_product_id: "com.example.kiosk.issue_2025_07"
                    external_id: "ISSUE-2025-07-REV-A"
                    hide_preview_widgets: true
                    single_purchase_required: false
                    for_subscribers_only: false
                    cents: 299
                    currency: "EUR"
                    category_ids: [508, 777]
                    text_mode_enabled: false
                    language: "de"

              updatePdfConfig:
                summary: Update the PDF import config (re-import)
                description: |
                  ATTENTION! Triggers a NEW import. The previous import is **deleted** and this action cannot be undone.
                value:
                  emag:
                    import_attributes:
                      import_images: false
                      pdf_location: "https://cdn.example.com/issues/2025_07/issue_v2.pdf"
                      xml_location: "https://cdn.example.com/issues/2025_07/issue_articles_v2.xml"

              switchToEpub:
                summary: NOT ALLOWED – switching import mode is forbidden
                description: |
                  Invalid request. Backend rejects with 400. Import mode (PDF vs EPUB) is immutable after creation.
                  You must update using the originally created import mode only.
                value:
                  emag:
                    epub_import_attributes:
                      import_articles: true
                      import_images: true
                      pdf_location: "https://cdn.example.com/issues/2025_07/issue.pdf"
                      epub_location: "https://cdn.example.com/issues/2025_07/issue.epub"

              updateAll:
                summary: Update ALL fields (meta + import) while keeping original mode (PDF)
                description: Demonstrates a full update without switching import mode.
                value:
                  emag:
                    name: "Issue July 2025 – Director's Cut"
                    released_at: "2025-07-15 09:30:00"
                    preview: "Completely revised teaser after editorial review."
                    apple_product_identifier: "com.example.kiosk.issue_2025_07_dc"
                    google_product_id: "com.example.kiosk.issue_2025_07_dc"
                    external_id: "ISSUE-2025-07-DC"
                    hide_preview_widgets: false
                    single_purchase_required: true
                    for_subscribers_only: false
                    cents: 399
                    currency: "EUR"
                    category_ids: [508, 642, 777]
                    text_mode_enabled: true
                    language: "de"
                    import_attributes:
                      import_images: true
                      pdf_location: "https://cdn.example.com/issues/2025_07/issue_dc.pdf"
                      xml_location: "https://cdn.example.com/issues/2025_07/issue_articles_dc.xml"

      responses:
        '200':
          description: Updated emag
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmagSuccessResponse'
              example:
                id: 12345
                created_at: "2025-08-01T12:10:00.000Z"
        '400':
          description: Validation errors
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                field_name: ["error message"]
        '401':
          description: Unauthorized (missing/invalid token)
        '404':
          description: emag not found
        '422':
          description: Unprocessable Entity (e.g. duplicate name, changing from PDF to EPUB import attributes)
        '500':
          description: Internal server error

  
