openapi: 3.0.0
info:
  title: MailScheduler
  description: |-
    Explore the MailScheduler API documentation, integrate MailScheduler with your data and maximizing the capabilities of our system. The MailScheduler API enables you to manage scheduled tasks, mailing lists, recipients, and more.

    ## Getting Started
    To begin using the MailScheduler API, follow these steps:

    ## Authentication:

    Obtain your API access token by providing your email and password into the login request. Details on authentication can be found on the /login endpoint.

    Once you have your access token, use it in the authorization header for all subsequent API requests. This ensures secure and authenticated communication with the MailScheduler system.

    ## Testing
    Please note that any changes made while testing in this documentation environment may impact the current tasks and database. Ensure you're in a dedicated testing environment to prevent unintended changes.

  version: 3.1-dev
servers:
  - url: '{protocol}://{serverUrl}/api'
    variables:
      protocol:
        enum:
          - 'http'
          - 'https'
        default: 'http'
      serverUrl:
        default: localhost:8000
        description: The (API) server url Server url. Usually similar to the URL in your browser
    description: Localhost test
security:
  - bearerAuth: []

tags:
  - name: Auth
    description: Get access to the API
  - name: Schedule
    description: View schedules
  - name: Task
    description: View and alter tasks
  - name: Mailinglist
    description: View and alter mailinglists
paths:
  /login:
    post:
      tags:
        - Auth
      summary: Authenticate and get a session token
      description: Authenticate and get a session token. This session token can be used for further authentication of all other requests.
      operationId: auth
      requestBody:
        description: Get a session token
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Auth'
        required: true
      responses:
        '200':
          $ref: '#/components/responses/AuthRes'
          description: Successful operation
        '401':
          description: Invalid input
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: boolean
                    example: false
                  err:
                    type: string
                    example: Incorrect login and password
  /schedules:
    get:
      tags:
        - Schedule
      summary: List all schedules
      description: Multiple status values can be provided with comma separated strings
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaginatedSchedule'
  /schedules/{scheduleId}/tasks:
    get:
      tags:
        - Task
      summary: View a task of a schedule
      parameters:
        - $ref: '#/components/parameters/scheduleId'
      responses:
        '200':
          description: successfully retrieved task
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskResponse'
        '404':
          $ref: '#/components/responses/404'
        '500':
          $ref: '#/components/responses/500'
    post:
      tags:
        - Task
      summary: Add a task to a schedule'
      parameters:
        - $ref: '#/components/parameters/scheduleId'

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskRequest'
      responses:
        '201':
          description: successfully created task
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskResponse'
        '422':
          $ref: '#/components/responses/422'
        '500':
          $ref: '#/components/responses/500'
  /schedules/{scheduleId}/tasks/{taskId}:
    parameters:
      - $ref: '#/components/parameters/scheduleId'
      - $ref: '#/components/parameters/taskId'
    put:
      tags:
        - Task
      summary: Update a task
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskRequest'
      responses:
        '200':
          description: successfully updated
        '422':
          $ref: '#/components/responses/422'
        '404':
          $ref: '#/components/responses/404'
        '500':
          $ref: '#/components/responses/500'

    delete:
      tags:
        - Task
      summary: Delete a task
      responses:
        '200':
          description: successfully deleted task
        '404':
          $ref: '#/components/responses/404'
        '500':
          $ref: '#/components/responses/500'
  /mailing-lists:
    get:
      tags:
        - Mailinglist
      summary: Get all mailinglists
      responses:
        '200':
          description: Get all mailinglists
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#components/responses/MailinglistResponse'
    post:
      tags:
        - Mailinglist
      summary: Create a new mailinglist
      requestBody:
        $ref: '#/components/requestBodies/MailinglistRequest'
        required: true
      responses:
        '201':
          description: Create a new mailinglist
          content:
            application/json:
              schema:
                $ref: '#/components/responses/MailinglistResponse'
        '422':
          $ref: '#/components/responses/422'
        '500':
          $ref: '#/components/responses/500'
  /mailing-lists/{mailinglistId}:
    parameters:
      - $ref: '#/components/parameters/mailinglistId'
    put:
      tags:
        - Mailinglist
      summary: Update a mailinglist
      requestBody:
        $ref: '#/components/requestBodies/MailinglistRequest'
        required: true
      responses:
        '200':
          description: Update a mailinglist
          content:
            application/json:
              schema:
                $ref: '#/components/responses/MailinglistResponse'
        '422':
          $ref: '#/components/responses/422'
        '404':
          $ref: '#/components/responses/404'
        '500':
          $ref: '#/components/responses/500'
    delete:
      tags:
        - Mailinglist
      summary: Delete a mailinglist
      responses:
        '200':
          description: successfully deleted mailinglist
        '404':
          $ref: '#/components/responses/404'
        '500':
          $ref: '#/components/responses/500'
  /recipients:
    get:
      tags:
        - Recipient
      summary: Get all recipients
      responses:
        '200':
          description: Get all recipients
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedRecipient'
    post:
      tags:
        - Recipient
      summary: Create a recipient
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecipientRequest'
      responses:
        '201':
          description: Store a new recipient
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Recipient'
        '422':
          $ref: '#/components/responses/422'
        '500':
          $ref: '#/components/responses/500'
  /recipients/{recipientId}:
    parameters:
      - $ref: '#/components/parameters/recipientId'
    put:
      tags:
        - Recipient
      summary: Update a recipient
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecipientRequest'
      responses:
        '200':
          description: successfully updated recipient
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
        '500':
          $ref: '#/components/responses/500'
    delete:
      tags:
        - Recipient
      summary: Delete a recipient
      responses:
        '200':
          description: successfully deleted recipient
        '422':
          $ref: '#/components/responses/422'
        '500':
          $ref: '#/components/responses/500'
  /sites:
    get:
      tags:
        - Sites
      responses:
        '200':
          description: Get all sites
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Site'
  /tableau/get-workbook-id/{siteId}:
    parameters:
      - $ref: '#/components/parameters/siteId'
    post:
      requestBody:
        $ref: '#/components/requestBodies/GetWorkbookIdRequest'
        required: true
      tags:
        - Tableau Helpers
      responses:
        '200':
          $ref: '#/components/responses/GetWorkbookIdRes'
  /tableau/get-view-id/{siteId}:
    parameters:
      - $ref: '#/components/parameters/siteId'
    post:
      requestBody:
        $ref: '#/components/requestBodies/GetViewIdRequest'
        required: true
      tags:
        - Tableau Helpers
      responses:
        '200':
          $ref: '#/components/responses/GetViewIdRes'
components:
  parameters:
    scheduleId:
      in: path
      name: scheduleId
      required: true
      description: Schedule ID
      schema:
        type: string
        example: 1
    taskId:
      in: path
      name: taskId
      required: true
      description: Task ID
      schema:
        type: string
        example: 1
    mailinglistId:
      in: path
      name: mailinglistId
      required: true
      description: Mailinglist ID
      schema:
        type: string
        example: 1
    recipientId:
      in: path
      name: recipientId
      required: true
      description: Recipient ID
      schema:
        type: string
        example: 1
    siteId:
      in: path
      name: siteId
      required: true
      description: Site ID, required to access Tableau
      schema:
        type: string
        example: 1

  schemas:
    Auth:
      type: object
      properties:
        email:
          type: string
          example: john@company.com
        password:
          type: string
    Filter:
      type: object
      properties:
        id:
          type: string
          example: 'temp-key-234'
        key:
          type: string
          example: Region
        value:
          type: string
          example: North
    View:
      type: object
      properties:
        id:
          type: string
          description: 'The id of the view. When you add a new view and you want to use it in the message as an inline image, you can give it a temp-12345 id and work with that.'
        label:
          type: string
          description: 'Recognizable label of the view'
        workbook_id:
          type: string
          description: Tableau workbook id. Obtain from Tableau API request
        view_id:
          type: string
          description: Tableau view id. Obtain from Tableau API request
        is_landscape:
          type: boolean
          description: When true, export in landscape orientation.
        order:
          type: integer
          description: The display order of the views. Use integers from 1 upwards.
          example: 1
        export_types:
          type: integer
          example: 2
          enum:
            - 2
            - 3
            - 4
            - 6
          description: >
            Export type:
              * 2 - PDF of the view
              * 3 - Excel crosstab of the view
              * 4 - CSV of the view
              * 6 - Image of the view
        filters:
          description: Filters for the view.
          type: array
          items:
            $ref: '#/components/schemas/Filter'
    Template:
      type: object
      properties:
        id:
          type: string
          description: The id of the template record
          example: 1
        label:
          type: string
          description: recognizable label for your reference
          example: company logo
        position:
          type: string
          description: The position of the template in the email.
          example: header-right
          enum:
            - header-left
            - header-center
            - header-right
            - body
            - footer-left
            - footer-center
            - footer-right
        is_global:
          type: boolean
          description: The template can be re-used if it is a global template. If not, it will only be used by this task in this email template position.
          example: true
        body:
          type: string
          description: Richtext body
          example: Hi {name}, Please see the overview below...
        img_id:
          type: string
          description: If you use an image file, specify the image ID.
          example: 2
        img_url:
          type: string
          description: If you use an image url, specify it here.
          example: https://website.com/images/company-logo.png
        img_width:
          type: integer
          description: Image width in px
          example: 200
        img_height:
          type: integer
          description: Image height in px
          example: 200
        img_align:
          type: string
          description: The aligment of the image within the cell. left, center, right
          example: right
          enum:
            - left
            - center
            - right

    TaskRequest:
      type: object
      properties:
        label:
          type: string
          example: Sales overview
          description: A recognizable label for your reference
        filename:
          type: string
          example: Sales
          description: The filename for the merged PDF.
        subject:
          type: string
          example: Weekly update
          description: Subject of the email
        mailinglists:
          type: array
          example: ['5', '7']
        emails:
          type: array
          example: [{ email: john@company.com }]
        send_type:
          type: string
          enum:
            - to
            - cc
            - bcc
          example: bcc
          description: Send the email with the following method
        from_email:
          type: string
          description: Email address to use in the from email field. Note that you need permission with the authenticated email account to send an email with this email address.
        from_name:
          type: string
          description: Name from in the email
        reply_to_email:
          type: string
          description: The reply to email address in the email
        reply_to_name:
          type: string
          description: The reply to name in the email

        active:
          type: boolean
          example: true
          description: When the task is active, it will be sent once the schedule is executed.
        save:
          type: boolean
          example: true
          description: Save a copy of the PDF on your server
        notify_on_failure:
          type: boolean
          example: true
          description: In case a task would fail, all recipients will get a notification that we were not able to send the email. We are aware of the issue and are working on it. This way we prevent that everyone will notify you about the failed email.
        csv_delimiter:
          type: string
          example: ','
          description: The delimiter to be used in your csv export
        csv_extension:
          type: string
          example: csv
          description: The extension for the csv export
        views:
          type: array
          items:
            $ref: '#/components/schemas/View'
        templates:
          type: array
          description: Templates are part of the email. You have templates for the headers and footers, but also for the main content of the email.
          items:
            $ref: '#/components/schemas/Template'
    TaskResponse:
      type: object
      properties:
        recipient_count:
          type: integer
          example: 1
        label:
          type: string
          example: Sales overview
          description: A recognizable label for your reference
        filename:
          type: string
          example: Sales
          description: The filename for the merged PDF.
        subject:
          type: string
          example: Weekly update
          description: Subject of the email
        mailinglists:
          type: array
          example: ['5', '7']
        emails:
          type: array
          example: [{ email: john@company.com }]
        send_type:
          type: string
          enum:
            - to
            - cc
            - bcc
          example: bcc
          description: Send the email with the following method
        from_email:
          type: string
          description: Email address to use in the from email field. Note that you need permission with the authenticated email account to send an email with this email address.
        from_name:
          type: string
          description: Name from in the email
        reply_to_email:
          type: string
          description: The reply to email address in the email
        reply_to_name:
          type: string
          description: The reply to name in the email

        active:
          type: boolean
          example: true
          description: When the task is active, it will be sent once the schedule is executed.
        save:
          type: boolean
          example: true
          description: Save a copy of the PDF on your server
        notify_on_failure:
          type: boolean
          example: true
          description: In case a task would fail, all recipients will get a notification that we were not able to send the email. We are aware of the issue and are working on it. This way we prevent that everyone will notify you about the failed email.
        csv_delimiter:
          type: string
          example: ','
          description: The delimiter to be used in your csv export
        csv_extension:
          type: string
          example: csv
          description: The extension for the csv export
        views:
          type: array
          items:
            $ref: '#/components/schemas/View'
        templates:
          type: array
          description: Templates are part of the email. You have templates for the headers and footers, but also for the main content of the email.
          items:
            $ref: '#/components/schemas/Template'
    RecipientRequest:
      type: object
      properties:
        name:
          type: string
          description: Name of the recipient. Primarely used for your reference, but acts as a fallback when you use the "name" placeholder
          example: John Doe
        email:
          type: string
          description: Emailaddress of the recipient
          example: john@company.com
        filters:
          type: array
          items:
            $ref: '#/components/schemas/Filter'
        placeholders:
          type: array
          items:
            $ref: '#/components/schemas/Placeholder'
        sites:
          type: array
          items:
            properties:
              id:
                type: string
                description: site id
        mailinglists:
          type: array
          items:
            type: string
            example: 5
    Placeholder:
      type: object
      properties:
        id:
          type: string
          example: 1
        key:
          type: string
          example: name
        value:
          type: string
          example: John Doe
    Paginated:
      type: object
      properties:
        current_page:
          type: integer
          example: 1
        last_page:
          type: integer
          example: 5
    Schedule:
      type: object
      properties:
        id:
          type: string
          description: Schedule ID.
          example: 3
        label:
          type: string
          description: Label of the schedule
          example: Weekly schedule
        admin_email:
          type: string
          description: Admin emailaddress
          example: admin@company.com
        testmode:
          type: boolean
          description: When in test mode only the admin gets an email
          example: true
        is_active:
          type: boolean
          description: Only when the task is active it will execute on the specified time
          example: true
        created_at:
          type: string
          format: date-time
          description: Created at timestamp
          example: '2024-01-01 09:10:00'
        updated_at:
          type: string
          format: date-time
          description: Updated at timestamp
          example: '2024-01-01 09:10:00'
        site_id:
          type: string
          description: The ID of the site the schedule is connected to.
          example: 2
        start_on:
          type: string
          format: date
          description: The date the schedule has to start
          example: '2024-01-01'
        end_on:
          type: string
          format: date
          description: The date the schedule has to end
          example: '2024-12-31'
        notify_on_failure:
          type: boolean
          description: Notify all recipient in case of failure. This way the recipients know we are aware of the issue and we look for a solution. Hence they won't feel the need to message you to notify you it is not working.
          example: false
        tasks_count:
          type: integer
          description: Number of tasks attached to this schedule
          example: 12
        active_tasks_count:
          type: integer
          description: Number of active tasks attached to this schedule
          example: 10
        upcoming:
          type: string
          format: date-time
          description: A timestamp that indicates the next moment the schedule will run. Note that this will not always display the correct value when using advanced triggers.
          example: '2024-02-26 09:00:00'
        frequencyString:
          type: string
          description: A string that describes the next moment the schedule will run. Note that this will not always display the correct value when using advanced triggers.
          example: 'Days of the week: MON -> Dailyat: 09:00'
        frequencies:
          type: string
          description: An object to specify and determine the trigger moment for the schedule. This is an advanced object and should not be tempered with.
          example: NA
    PaginatedSchedule:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Schedule'
        current_page:
          type: integer
          example: 1
        last_page:
          type: integer
          example: 5
    Recipient:
      type: object
      properties:
        name:
          type: string
          description: Name of the recipient. Primarely used for your reference, but acts as a fallback when you use the "name" placeholder
          example: John Doe
        email:
          type: string
          description: Emailaddress of the recipient
          example: john@company.com
        filters:
          type: array
          items:
            $ref: '#/components/schemas/Filter'
        placeholders:
          type: array
          items:
            $ref: '#/components/schemas/Placeholder'
        sites:
          type: array
          items:
            properties:
              id:
                type: string
                description: site id
        mailinglists:
          type: array
          items:
            type: string
            example: 5
        created_at:
          type: string
          description: Created at timestamp
          example: '2024-01-17T09:45:14.000000Z'
        updated_at:
          type: string
          description: Updated at timestamp
          example: '2024-01-17T09:45:14.000000Z'
    PaginatedRecipient:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Recipient'
        current_page:
          type: integer
          example: 1
        last_page:
          type: integer
          example: 5

    Site:
      type: object
      properties:
        id:
          type: string
          description: site ID
        label:
          type: string
          description: site label
        site_name:
          type: string
          example: companyname
        token_id:
          type: string
          example: '1'
        server_id:
          type: string
          example: 1

    SiteOption:
      type: object
      properties:
        id:
          type: string
          description: site ID
        label:
          type: string
          description: site label

  requestBodies:
    Task:
      description: Body of a new task request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TaskRequest'
    MailinglistRequest:
      description: Request for mailinglist
      content:
        application/json:
          schema:
            type: object
            properties:
              name:
                type: string
                description: The label of the mailinglist
                example: Managers
              description:
                type: string
                description: A description for the mailinglist
                example: Managers from region West
              sites:
                type: array
                items:
                  properties:
                    id:
                      type: string
                      description: site id. These can be found in the sites request.
                      example: 2
    GetWorkbookIdRequest:
      description: Request to find workbook ID from Tableau.
      content:
        application/json:
          schema:
            type: object
            properties:
              name:
                type: string
                description: The name of the workbook
                example: MyWorkbook
    GetViewIdRequest:
      description: Request to find view ID from Tableau.
      content:
        application/json:
          schema:
            type: object
            properties:
              name:
                type: string
                description: The name of the Dashboard or view
                example: MyDashboardName
  responses:
    MailinglistResponse:
      description: Mailinglist Response.
      content:
        application/json:
          schema:
            type: object
            properties:
              id:
                type: string
                description: Mailinglist ID
                example: 3
              name:
                type: string
                description: The label of the mailinglist
                example:
              description:
                type: string
                description: A description for the mailinglist
                example: Managers from region West
              created_at:
                type: string
                description: Created at timestamp
                example: '2023-12-21T09:24:39.000000Z'
              updated_at:
                type: string
                description: Updated at timestamp
                example: '2023-12-21T09:24:39.000000Z'
              recipients_count:
                type: string
                description: Number of recipients attached to this mailinglist
                example: 12
              site_names:
                type: string
                description: The names of the sites this mailing list is connected to
                example:
              recipients:
                type: array
                description: The recipents in this mailinglist
                items:
                  $ref: '#/components/schemas/Recipient'
              sites:
                type: array
                description: Sites connected to this mailinglist
                items:
                  $ref: '#/components/schemas/SiteOption'

    AuthRes:
      description: Auth response. Find the token here and use this as authentication for the other requests.
      content:
        application/json:
          schema:
            type: object
            properties:
              user:
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
                  email:
                    type: string
                  email_verified_at:
                    type: string
                  is_admin:
                    type: string
                  created_at:
                    type: string
                  updated_at:
                    type: string
              token:
                type: string
                example: 21|wefoefkweofkewf324903kefl
          examples:
            'John':
              value:
                user:
                  id: '1'
                  name: John Doe
                  email: john@company.com
                  email_verified_at: null,
                  is_admin: true
                  created_at: '2023-10-03T08:16:46.000000Z'
                  updated_at: '2023-11-20T13:58:04.000000Z'
                token: 8|RSX9LwIKpiXdiMr73KOG0gpoEtD8LrMRLuhQOF8u98cfe793

    GetWorkbookIdRes:
      description: Get back the workbook ID from Tableau
      content:
        application/json:
          schema:
            type: object
            properties:
              workbookd_id:
                type: string
                example: 3a051b9c-e21a-4a77-b809-6d2d0a9f2305
    GetViewIdRes:
      description: Get back the view ID from Tableau
      content:
        application/json:
          schema:
            type: object
            properties:
              view_id:
                type: string
                example: 3a051b9c-e21a-4a77-b809-6d2d0a9f2305

    500:
      description: Server error
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: boolean
                example: false
              status_code:
                type: integer
                example: 500
              reason_phrase:
                type: string
                example: Reason phrase

    404:
      description: Model not found
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: boolean
                example: false
              status_code:
                type: integer
                example: 500
              reason_phrase:
                type: string
                example: Reason phrase
          examples:
            'Model missing':
              value:
                status: false
                status_code: 404
                reason_phrase: No query results for model [App\\Models\\Model] 1

    422:
      description: Unprocessable Content
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                example: The X field is required. (and 2 more errors)
              errors:
                type: array
                items:
                  properties:
                    fieldname:
                      type: array
                      items:
                        description: fieldname - error string
                        example: The X field is required.
          examples:
            'FieldsMissing':
              value:
                message: The X field is required. (and 2 more errors)
                errors:
                  - site_id:
                      - The X field is required.
                  - label:
                      - The Y field is required.
                  - admin_email:
                      - The Z field is required.

  securitySchemes:
    # basicAuth:
    #   type: http
    #   scheme: basic
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
