openapi: 3.0.3
info:
  title: New Xperience REST API
  description: |
    API documentation for the New Xperience (XNEW) REST API.
  version: "1"
  contact:
    url: https://apidocs.inxmail.com/xnew/rest/v1/

servers:
  - url: https://{tenant}.my-api.inxmail.de
    description: New Xperience REST API
    variables:
      tenant:
        description: Your tenant identifier (e.g. myka-1)
        default: myka-1

security:
  - basicAuth: []

tags:
  - name: Mailings
    description: Operations for managing Mailings
  - name: Mailing Templates
    description: Operations for retrieving Mailing Templates
  - name: Blocklist
    description: Operations for managing the domain and email blocklist
  - name: Accessible Customers
    description: Operations for retrieving accessible Inxmail Professional customers and their lists
  - name: Mailing Synchronizations
    description: Operations for synchronizing mailings with Inxmail Professional

paths:

  # ─── Mailings ────────────────────────────────────────────────────────────────

  /mailings:

    get:
      tags: [Mailings]
      summary: List Mailings
      operationId: listMailings
      description: Returns a list of Mailings sorted by the `modificationDate` property in descending order.
      parameters:
        - name: isApproved
          in: query
          required: false
          description: |
            Filters Mailings based on whether they are approved (`true`) or not (`false`).

            **Constraint:** `hasDraft` and `isApproved` cannot simultaneously be `false`.
          schema:
            type: boolean
        - name: hasDraft
          in: query
          required: false
          description: |
            Filters Mailings based on whether they have a draft version (`true`) or not (`false`).

            **Constraint:** `hasDraft` and `isApproved` cannot simultaneously be `false`.
          schema:
            type: boolean
        - name: id
          in: query
          required: false
          description: Returns Mailings for a list of comma-separated IDs. Must not exceed 50 IDs.
          schema:
            type: string
            example: "a9656ccc-15b3-4fe5-a1c7-800f0856d7a0,0d8fe260-7b9f-43e0-9ba8-ac182846e570"
        - name: pageSize
          in: query
          required: false
          description: Specifies the number of results per page.
          schema:
            type: integer
            default: 1000
      responses:
        "200":
          description: A HAL+JSON list of Mailings.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/MailingListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

    post:
      tags: [Mailings]
      summary: Create a Mailing
      operationId: createMailing
      description: |
        Creates a new Mailing based on an already existing and `approved` Mailing Template,
        which can be edited using the New Xperience Mailing Editor.
      parameters:
        - name: mailingTemplateId
          in: query
          required: true
          description: The ID of the `approved` Mailing Template to base the new Mailing on.
          schema:
            type: string
            format: uuid
            example: "e420c737-5378-4f4b-a79b-c55adba548db"
      requestBody:
        required: true
        content:
          application/hal+json:
            schema:
              $ref: "#/components/schemas/CreateMailingRequest"
            example:
              name: "My first Mailing based on a Mailing Template"
      responses:
        "201":
          description: Mailing created successfully.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/CreateMailingResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /mailings/{id}:

    get:
      tags: [Mailings]
      summary: Get a Mailing
      operationId: getMailing
      description: Retrieves a single Mailing by its ID.
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the Mailing.
          schema:
            type: string
            format: uuid
            example: "cb6341d8-e44b-4586-a383-d02e7db5b873"
      responses:
        "200":
          description: The requested Mailing.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/MailingResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  # ─── Mailing Templates ───────────────────────────────────────────────────────

  /mailing-templates:

    get:
      tags: [Mailing Templates]
      summary: List Mailing Templates
      operationId: listMailingTemplates
      description: Returns a list of Mailing Templates sorted by the `name` property.
      parameters:
        - name: order
          in: query
          required: false
          description: Orders Mailing Templates `asc` (ascending) or `desc` (descending) by name. Default is `asc`. Case insensitive.
          schema:
            type: string
            enum: [asc, desc]
            default: asc
        - name: isApproved
          in: query
          required: false
          description: |
            Filters Mailing Templates based on whether they are approved.

            **Constraint:** `hasDraft` and `isApproved` cannot simultaneously be `false`.
          schema:
            type: boolean
        - name: hasDraft
          in: query
          required: false
          description: |
            Filters Mailing Templates based on whether they have a draft version.

            **Constraint:** `hasDraft` and `isApproved` cannot simultaneously be `false`.
          schema:
            type: boolean
        - name: pageSize
          in: query
          required: false
          description: Specifies the number of results per page.
          schema:
            type: integer
            default: 1000
      responses:
        "200":
          description: A HAL+JSON list of Mailing Templates.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/MailingTemplateListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

  # ─── Blocklist ───────────────────────────────────────────────────────────────

  /blocklist/isBlocklisted:

    get:
      tags: [Blocklist]
      summary: Check blocklist
      operationId: checkBlocklist
      description: |
        Check if a domain or email address is blocked. The parameters `domain` and `email` are mutually exclusive.

        - If checking for a **domain**, only domain blocklist entries are considered.
        - If checking for an **email address**, both domain and email blocklist entries are considered.
          The more specific match (email entry) takes precedence.
      parameters:
        - name: domain
          in: query
          required: false
          description: The domain to check. Mutually exclusive with `email`.
          schema:
            type: string
            example: "inxmail.de"
        - name: email
          in: query
          required: false
          description: The email address to check. Mutually exclusive with `domain`.
          schema:
            type: string
            format: email
            example: "name@inxmail.de"
      responses:
        "200":
          description: Blocklist check result.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/BlocklistCheckResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /blocklist/domains:

    get:
      tags: [Blocklist]
      summary: List all domain blocklist entries
      operationId: listDomainBlocklistEntries
      description: Returns all entries in the domain blocklist.
      parameters:
        - $ref: "#/components/parameters/syncModifications"
        - $ref: "#/components/parameters/syncToken"
      responses:
        "200":
          description: A HAL+JSON list of domain blocklist entries.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/DomainBlocklistListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

    post:
      tags: [Blocklist]
      summary: Create a domain blocklist entry
      operationId: createDomainBlocklistEntry
      description: Creates an entry in the domain blocklist.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateDomainBlocklistEntryRequest"
            example:
              domain: "invalid.de"
              reason: "SPAM"
      responses:
        "201":
          description: Domain blocklist entry created.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/BlocklistEntryResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /blocklist/domains/{id}:

    delete:
      tags: [Blocklist]
      summary: Delete a domain blocklist entry
      operationId: deleteDomainBlocklistEntry
      description: Deletes an entry in the domain blocklist.
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the domain blocklist entry.
          schema:
            type: string
            example: "62c53066f0241523892587e2"
      responses:
        "204":
          description: Domain blocklist entry deleted successfully.
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /blocklist/emails:

    get:
      tags: [Blocklist]
      summary: List all email blocklist entries
      operationId: listEmailBlocklistEntries
      description: Returns all entries in the email blocklist.
      parameters:
        - $ref: "#/components/parameters/syncModifications"
        - $ref: "#/components/parameters/syncToken"
      responses:
        "200":
          description: A HAL+JSON list of email blocklist entries.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/EmailBlocklistListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

    post:
      tags: [Blocklist]
      summary: Create an email blocklist entry
      operationId: createEmailBlocklistEntry
      description: Creates an entry in the email blocklist.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateEmailBlocklistEntryRequest"
            example:
              email: "invalid@inxmail.de"
              reason: "SPAM"
      responses:
        "201":
          description: Email blocklist entry created.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/BlocklistEntryResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /blocklist/emails/{id}:

    delete:
      tags: [Blocklist]
      summary: Delete an email blocklist entry
      operationId: deleteEmailBlocklistEntry
      description: Deletes an entry in the email blocklist.
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the email blocklist entry.
          schema:
            type: string
            example: "62c5321ff0241523892587e3"
      responses:
        "204":
          description: Email blocklist entry deleted successfully.
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  # ─── Accessible Customers ────────────────────────────────────────────────────

  /integrations/inxmail-professional/accessible-customers:

    get:
      tags: [Accessible Customers]
      summary: List accessible customers
      operationId: listAccessibleCustomers
      description: Returns a list of accessible Inxmail Professional customers.
      responses:
        "200":
          description: A HAL+JSON list of accessible customers.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/AccessibleCustomerListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /integrations/inxmail-professional/accessible-customers/{customerName}:

    get:
      tags: [Accessible Customers]
      summary: Get a single accessible customer
      operationId: getAccessibleCustomer
      parameters:
        - name: customerName
          in: path
          required: true
          description: The name of the accessible customer.
          schema:
            type: string
            example: "myka"
      responses:
        "200":
          description: The requested accessible customer.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/AccessibleCustomerResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /integrations/inxmail-professional/accessible-customers/{customerName}/lists:

    get:
      tags: [Accessible Customers]
      summary: List Inxmail Professional lists for a customer
      operationId: listInxmailProfessionalLists
      parameters:
        - name: customerName
          in: path
          required: true
          description: The name of the accessible customer.
          schema:
            type: string
            example: "myka"
        - name: showAllLists
          in: query
          required: false
          description: Returns all available lists for the customer without any filtering or restrictions.
          schema:
            type: boolean
      responses:
        "200":
          description: A HAL+JSON list of Inxmail Professional lists.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/InxmailListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

  # ─── Mailing Synchronizations ────────────────────────────────────────────────

  /integrations/inxmail-professional/mailing-synchronizations:

    get:
      tags: [Mailing Synchronizations]
      summary: List Mailing Synchronizations
      operationId: listMailingSynchronizations
      parameters:
        - $ref: "#/components/parameters/syncModifications"
        - $ref: "#/components/parameters/syncToken"
        - name: mailingId
          in: query
          required: false
          description: Returns mailing-synchronizations for a list of comma-separated New Xperience mailing IDs.
          schema:
            type: string
        - name: readyForSending
          in: query
          required: false
          description: Returns all mailing-synchronizations with an approved mailing.
          schema:
            type: boolean
        - name: mailingHasDraft
          in: query
          required: false
          description: Returns all mailing-synchronizations with a draft mailing.
          schema:
            type: boolean
        - name: mailingIsApproved
          in: query
          required: false
          description: Returns all mailing-synchronizations with an approved mailing.
          schema:
            type: boolean
        - name: sortBy
          in: query
          required: false
          description: "Sorts by: `creationDate`, `modificationDate` or `mailingName`. Cannot be used with `syncModifications`."
          schema:
            type: string
            enum: [creationDate, modificationDate, mailingName]
        - name: order
          in: query
          required: false
          description: Orders `asc` or `desc`. Cannot be used with `syncModifications`.
          schema:
            type: string
            enum: [asc, desc]
            default: asc
        - name: pageSize
          in: query
          required: false
          description: Specifies the number of results per page.
          schema:
            type: integer
            default: 1000
      responses:
        "200":
          description: A HAL+JSON list of Mailing Synchronizations.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/MailingSynchronizationListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

    post:
      tags: [Mailing Synchronizations]
      summary: Create a Mailing Synchronization
      operationId: createMailingSynchronization
      description: |
        Creates a new mailing synchronization. Providing `mailingId` links an existing New Xperience mailing.
        `mailingId` and `templateMailingId` are mutually exclusive.
      requestBody:
        required: true
        content:
          application/hal+json:
            schema:
              $ref: "#/components/schemas/CreateMailingSynchronizationRequest"
            example:
              customer: "mrm"
              listId: 6
              mailingName: "My first Mailing"
      responses:
        "201":
          description: Mailing Synchronization created.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/MailingSynchronizationResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /integrations/inxmail-professional/mailing-synchronizations/{id}:

    get:
      tags: [Mailing Synchronizations]
      summary: Get a Mailing Synchronization
      operationId: getMailingSynchronization
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: The requested Mailing Synchronization.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/MailingSynchronizationResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /integrations/inxmail-professional/mailing-synchronizations/{id}/preview:

    get:
      tags: [Mailing Synchronizations]
      summary: Get mailing preview
      operationId: getMailingPreview
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
        - name: kind
          in: query
          required: false
          description: Which version to preview. `latest` (default), `draft` or `lastApproved`.
          schema:
            type: string
            enum: [latest, draft, lastApproved]
            default: latest
        - name: testProfileId
          in: query
          required: false
          description: ID of a test profile from Inxmail Professional for personalized preview.
          schema:
            type: integer
      responses:
        "200":
          description: The mailing preview.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/MailingPreviewResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /integrations/inxmail-professional/mailing-synchronizations/{id}/mailing-uploads:

    post:
      tags: [Mailing Synchronizations]
      summary: Create a mailing upload
      operationId: createMailingUpload
      description: Creates a mailing in the Inxmail Professional list associated to the mailing synchronization.
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/hal+json:
            schema:
              type: object
      responses:
        "200":
          description: Mailing upload created.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/MailingUploadResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /integrations/inxmail-professional/mailing-synchronizations/{syncId}/mailing-uploads/{id}:

    get:
      tags: [Mailing Synchronizations]
      summary: Get a mailing upload
      operationId: getMailingUpload
      description: Use `latest` as `id` to retrieve the most recent mailing upload.
      parameters:
        - name: syncId
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
        - name: id
          in: path
          required: true
          description: The ID of the mailing upload, or `latest` for the most recent one.
          schema:
            type: string
            example: "f992c6a4-dffa-4e33-baad-7f1206371166"
      responses:
        "200":
          description: The requested mailing upload.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/MailingUploadResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /integrations/inxmail-professional/mailing-synchronizations/{syncId}/mailing-uploads/{id}/content-updates:

    post:
      tags: [Mailing Synchronizations]
      summary: Update mailing upload content
      operationId: updateMailingUploadContent
      description: Updates the mailing content of an existing mailing upload.
      parameters:
        - name: syncId
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
        - name: id
          in: path
          required: true
          description: The ID of the mailing upload.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/hal+json:
            schema:
              type: object
      responses:
        "200":
          description: Mailing upload content updated.
          content:
            application/json:
              schema:
                type: object
                properties:
                  modificationDate:
                    type: string
                    format: date-time
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /integrations/inxmail-professional/mailing-synchronizations/{id}/sendings:

    get:
      tags: [Mailing Synchronizations]
      summary: List sendings
      operationId: listSendings
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
        - name: pageSize
          in: query
          required: false
          description: Specifies the number of results per page.
          schema:
            type: integer
            default: 1000
      responses:
        "200":
          description: A HAL+JSON list of sendings.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/SendingListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

    post:
      tags: [Mailing Synchronizations]
      summary: Create a sending
      operationId: createSending
      description: |
        Creates a sending for the given Mailing Synchronization. The New Xperience mailing must be approved
        (indicated by the `readyForSending` flag). Returns successfully once the setup is done; does not block
        until sending is complete.
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/hal+json:
            schema:
              $ref: "#/components/schemas/CreateSendingRequest"
      responses:
        "201":
          description: Sending created.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/SendingResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /integrations/inxmail-professional/mailing-synchronizations/{syncId}/sendings/{id}:

    get:
      tags: [Mailing Synchronizations]
      summary: Get a sending
      operationId: getSending
      parameters:
        - name: syncId
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
        - name: id
          in: path
          required: true
          description: The ID of the sending.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: The requested sending.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/SendingResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /integrations/inxmail-professional/mailing-synchronizations/{syncId}/sendings/{sendingId}/statistics:

    get:
      tags: [Mailing Synchronizations]
      summary: Get sending statistics
      operationId: getSendingStatistics
      parameters:
        - name: syncId
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
        - name: sendingId
          in: path
          required: true
          description: The ID of the sending.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Sending statistics.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/SendingStatisticsResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /integrations/inxmail-professional/mailing-synchronizations/{id}/test-sendings:

    post:
      tags: [Mailing Synchronizations]
      summary: Create a test sending
      operationId: createTestSending
      description: Sends a test mailing. `recipientAddresses` and `testMailGroupId` are mutually exclusive.
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/hal+json:
            schema:
              $ref: "#/components/schemas/CreateTestSendingRequest"
            example:
              testProfileId: 10
              recipientAddresses:
                - "somebody@dummy.invalid"
                - "somebodyelse@dummy.invalid"
      responses:
        "202":
          description: Test sending accepted.
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /integrations/inxmail-professional/mailing-synchronizations/{id}/test-profiles:

    get:
      tags: [Mailing Synchronizations]
      summary: List test profiles
      operationId: listTestProfiles
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: A HAL+JSON list of test profiles.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/TestProfileListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

  /integrations/inxmail-professional/mailing-synchronizations/{id}/test-mail-groups:

    get:
      tags: [Mailing Synchronizations]
      summary: List test mail groups
      operationId: listTestMailGroups
      parameters:
        - name: id
          in: path
          required: true
          description: The ID of the Mailing Synchronization.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: A HAL+JSON list of test mail groups.
          content:
            application/hal+json:
              schema:
                $ref: "#/components/schemas/TestMailGroupListResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

components:

  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: Base64-encoded `user:password` credentials.

  parameters:
    syncModifications:
      name: syncModifications
      in: query
      required: false
      description: See chapter "Synchronize Resources Efficiently".
      schema:
        type: boolean
    syncToken:
      name: syncToken
      in: query
      required: false
      description: See chapter "Synchronize Resources Efficiently".
      schema:
        type: string

  responses:
    Unauthorized:
      description: "Unauthorized – missing or invalid credentials."
    BadRequest:
      description: "Bad request – e.g. missing required fields or invalid values."
    NotFound:
      description: "Not found – the requested resource does not exist."

  schemas:

    # ── HAL primitives ──────────────────────────────────────────────────────────

    HalLink:
      type: object
      description: A HAL hyperlink object.
      properties:
        href:
          type: string
          format: uri
        templated:
          type: boolean
          default: false
      required: [href]

    HalCurie:
      type: object
      description: A HAL CURIE entry for namespaced link relations.
      properties:
        href:
          type: string
          format: uri
        name:
          type: string
        templated:
          type: boolean
      required: [href, name]

    # ── Mailings ────────────────────────────────────────────────────────────────

    MailingLinks:
      type: object
      properties:
        self:
          $ref: "#/components/schemas/HalLink"
        "inx:mailing-editor":
          allOf:
            - $ref: "#/components/schemas/HalLink"
          description: Link to open the New Xperience Mailing Editor for this Mailing.
        curies:
          type: array
          items:
            $ref: "#/components/schemas/HalCurie"

    MailingItem:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        creationDate:
          type: string
          format: date-time
        modificationDate:
          type: string
          format: date-time
        isApproved:
          type: boolean
        hasDraft:
          type: boolean
        _links:
          $ref: "#/components/schemas/MailingLinks"
      required: [id, name, creationDate, modificationDate, isApproved, hasDraft]

    MailingListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:mailings":
              type: array
              items:
                $ref: "#/components/schemas/MailingItem"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    MailingResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        _links:
          $ref: "#/components/schemas/MailingLinks"
      required: [id]

    CreateMailingRequest:
      type: object
      properties:
        name:
          type: string
          maxLength: 255
          description: "Must not be null or empty, must contain at least one non-whitespace character, max 255 chars."
        subject:
          type: string
          description: "Optional: initial subject. If not set, the name is used."
        preheader:
          type: string
          description: "Optional: initial preheader."
      required: [name]

    CreateMailingResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        _links:
          $ref: "#/components/schemas/MailingLinks"
      required: [id]

    # ── Mailing Templates ───────────────────────────────────────────────────────

    MailingTemplateItem:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        isApproved:
          type: boolean
        hasDraft:
          type: boolean

    MailingTemplateListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:mailing-templates":
              type: array
              items:
                $ref: "#/components/schemas/MailingTemplateItem"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            next:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    # ── Blocklist ───────────────────────────────────────────────────────────────

    BlocklistReason:
      type: string
      enum: [SPAM, COMPETITION, ADVERTISING_BLOCKER, LEGAL_REASON]
      description: The reason for the blocking decision.

    BlocklistHit:
      type: object
      properties:
        id:
          type: string
        type:
          type: string
          enum: [DOMAIN, EMAIL]
        reason:
          $ref: "#/components/schemas/BlocklistReason"
        blockedSince:
          type: string
          format: date-time

    BlocklistCheckResponse:
      type: object
      properties:
        searchValue:
          type: string
          description: The value that was supplied in the domain or email query parameter.
        blocked:
          type: boolean
          description: Indicates if the domain or email address is blocked.
        hits:
          type: array
          items:
            $ref: "#/components/schemas/BlocklistHit"
        _links:
          type: object
          additionalProperties:
            $ref: "#/components/schemas/HalLink"

    BlocklistEntryResponse:
      type: object
      properties:
        id:
          type: string
        hash:
          type: string
        dateCreated:
          type: string
          format: date-time
        blockedReason:
          $ref: "#/components/schemas/BlocklistReason"
        blockedBy:
          type: string
          format: uuid
        domain:
          type: string
          description: Present for domain blocklist entries.
        email:
          type: string
          format: email
          description: Present for email blocklist entries.
        type:
          type: string
          enum: [DOMAIN, EMAIL]
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"

    CreateDomainBlocklistEntryRequest:
      type: object
      properties:
        domain:
          type: string
          description: The domain to block. Must not be null or empty.
        reason:
          $ref: "#/components/schemas/BlocklistReason"
      required: [domain]

    CreateEmailBlocklistEntryRequest:
      type: object
      properties:
        email:
          type: string
          format: email
          description: The email address to block. Must be a well-formed email address.
        reason:
          $ref: "#/components/schemas/BlocklistReason"
      required: [email]

    DomainBlocklistListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:domains":
              type: array
              items:
                $ref: "#/components/schemas/BlocklistEntryResponse"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            next:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    EmailBlocklistListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:emails":
              type: array
              items:
                $ref: "#/components/schemas/BlocklistEntryResponse"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            next:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    # ── Accessible Customers ────────────────────────────────────────────────────

    AccessibleCustomerResponse:
      type: object
      properties:
        name:
          type: string
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"

    AccessibleCustomerListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:accessible-customers":
              type: array
              items:
                $ref: "#/components/schemas/AccessibleCustomerResponse"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    InxmailListItem:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"

    InxmailListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:lists":
              type: array
              items:
                $ref: "#/components/schemas/InxmailListItem"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    # ── Mailing Synchronizations ────────────────────────────────────────────────

    MailingSynchronizationTarget:
      type: object
      properties:
        customer:
          type: string
        listId:
          type: integer
        listName:
          type: string

    MailingSynchronizationResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        creationDate:
          type: string
          format: date-time
        modificationDate:
          type: string
          format: date-time
          nullable: true
        mailingId:
          type: string
          format: uuid
        mailingName:
          type: string
        approvedMailingName:
          type: string
          nullable: true
        readyForSending:
          type: boolean
        mailingHasDraft:
          type: boolean
        mailingIsApproved:
          type: boolean
        target:
          $ref: "#/components/schemas/MailingSynchronizationTarget"
        mailingUploadsModificationDate:
          type: string
          format: date-time
          nullable: true
        sendingsModificationDate:
          type: string
          format: date-time
          nullable: true
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            "inx:mailing-editor":
              $ref: "#/components/schemas/HalLink"
            "inx:mailing-preview-draft":
              $ref: "#/components/schemas/HalLink"
            "inx:mailing-preview-approved":
              $ref: "#/components/schemas/HalLink"
            "inx:sendings":
              $ref: "#/components/schemas/HalLink"
            "inx:mailing-uploads":
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    MailingSynchronizationListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:mailing-synchronizations":
              type: array
              items:
                $ref: "#/components/schemas/MailingSynchronizationResponse"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            next:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    CreateMailingSynchronizationRequest:
      type: object
      properties:
        customer:
          type: string
          description: The Inxmail Professional customer alias. Must be configured for the current tenant.
        listId:
          type: integer
          description: The ID of the Inxmail Professional list.
        mailingName:
          type: string
          description: "Optional: initial name of the mailing. Defaults to 'New Mailing'."
        mailingId:
          type: string
          format: uuid
          description: "Optional: an existing New Xperience mailing to synchronize. Mutually exclusive with templateMailingId."
        templateMailingId:
          type: string
          format: uuid
          description: "Optional: an existing New Xperience mailing to use as template. Mutually exclusive with mailingId."
      required: [customer, listId]

    MailingUploadTarget:
      type: object
      properties:
        mailingId:
          type: integer

    MailingUploadResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        creationDate:
          type: string
          format: date-time
        modificationDate:
          type: string
          format: date-time
        target:
          $ref: "#/components/schemas/MailingUploadTarget"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    SendingTarget:
      type: object
      properties:
        mailingId:
          type: integer
        sendingId:
          type: integer

    SendingResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        creationDate:
          type: string
          format: date-time
        scheduleDate:
          type: string
          format: date-time
          nullable: true
        mailingSynchronizationId:
          type: string
          format: uuid
        target:
          $ref: "#/components/schemas/SendingTarget"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            "inx:report":
              $ref: "#/components/schemas/HalLink"
            "inx:statistics":
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    SendingListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:sendings":
              type: array
              items:
                $ref: "#/components/schemas/SendingResponse"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    CreateSendingRequest:
      type: object
      properties:
        scheduleDate:
          type: string
          format: date-time
          description: "Optional: if not defined, the mailing will be sent immediately."
        name:
          type: string
          description: "Optional: overrides the mailing name."
        subject:
          type: string
          description: "Optional: overrides the mailing subject."

    CreateTestSendingRequest:
      type: object
      properties:
        testProfileId:
          type: integer
          description: "ID of the test profile for personalization. If not provided, an empty profile is used."
        recipientAddresses:
          type: array
          items:
            type: string
            format: email
          description: "Email addresses of test recipients. Mutually exclusive with testMailGroupId."
        testMailGroupId:
          type: integer
          description: "ID of the test mail group. Mutually exclusive with recipientAddresses."
        kind:
          type: string
          enum: [latest, draft, lastApproved]
          default: latest
        subjectPrefix:
          type: string
          description: "Optional prefix for the mailing subject."

    MailingPreviewResponse:
      type: object
      properties:
        htmlContent:
          type: string
        textContent:
          type: string
        subject:
          type: string
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"

    SendingStatisticsResponse:
      type: object
      properties:
        synchronizationId:
          type: string
          format: uuid
        responseStatistics:
          type: object
          properties:
            clickingRecipients:
              type: integer
            ctor:
              type: number
            openingRate:
              type: number
            openingRecipients:
              type: integer
            totalClicks:
              type: integer
            uniqueClickRate:
              type: number
            unsubscribeClicks:
              type: integer
            listUnsubscribeClicks:
              type: integer
            unsubscribeRate:
              type: number
        sendingStatistics:
          type: object
          properties:
            averageMailSize:
              type: number
            bounceCount:
              type: integer
            deliveredMailsCount:
              type: integer
            mailsPerHour:
              type: number
            notSentMailsCount:
              type: integer
            recipientsCount:
              type: integer
            sentErrorCount:
              type: integer
            startDate:
              type: string
              format: date-time
            endDate:
              type: string
              format: date-time
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"

    TestProfileItem:
      type: object
      properties:
        id:
          type: integer
        description:
          type: string

    TestProfileListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:test-profiles":
              type: array
              items:
                $ref: "#/components/schemas/TestProfileItem"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"

    TestMailGroupItem:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        emails:
          type: array
          items:
            type: string
            format: email

    TestMailGroupListResponse:
      type: object
      properties:
        _embedded:
          type: object
          properties:
            "inx:test-mail-groups":
              type: array
              items:
                $ref: "#/components/schemas/TestMailGroupItem"
        _links:
          type: object
          properties:
            self:
              $ref: "#/components/schemas/HalLink"
            curies:
              type: array
              items:
                $ref: "#/components/schemas/HalCurie"
