openapi: 3.1.0
info:
  title: Cyberimpact API
  x-logo:
    url: "/docs/assets/logo-white.png"
    altText: 'Cyberimpact'
  description: |
    Welcome to the Cyberimpact API. With it, you can interact with your Cyberimpact account programmatically.
    Our API is based on REST principles. The following documentation covers core resources.

    First of all, read these basic instructions to start using the API:

    - You must authenticate to the Cyberimpact's API with a [JSON Web Token (JWT)](http://jwt.io/introduction/) generated in the application (or via the API) using the *Authorization: Bearer token-content* HTTP header
    - The URL for the Cyberimpact API is located at https://api.cyberimpact.com
    - Submit all your requests (for POST, PUT, PATCH) in JSON
    - Submit all your requests using the UTF-8 character encoding
    - Cyberimpact API uses standard HTTP response codes to indicate the success or failure of a request. Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error.

    ## Authentication
    
    The Cyberimpact API uses API tokens to authenticate requests. You can view and manage your API tokens in the Developers / API tokens menu of the Cyberimpact application.
    
    Your API tokens carry many privileges, so share them securely and only with people you trust. They are the access to your account, so this information should not be public.
    
    Authentication to the API is performed via bearer authentication. Just add a "Authorization: Bearer YOUR_JWT_ACCESS_TOKEN" HTTP header to each of your requests. You can browse the Resources section of this documentation for examples in different programming languages.

    ## Universal query parameter: dateReturnFormat

    By default, the API returns every date in the format `Y-m-d H:i:s.u` in the EST/EDT timezone.

    To receive dates in a standard format with timezone, add the `dateReturnFormat` query parameter to any request.

    Available values:
    - `ISO8601`
    - `ATOM`

    Example: `https://api.cyberimpact.com/members?dateReturnFormat=ISO8601`

    Note: This parameter only affects returned dates — you must still send dates in the format documented per endpoint.

servers:
  - url: https://api.cyberimpact.com

security:
  - bearerAuth: [ ]

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    Member:
      type: object
      properties:
        id:
          type: integer
          example: 3664823
        firstname:
          type: string
          example: John
        lastname:
          type: string
          example: Doe
        company:
          type: string
          example: John Doe Company inc
        email:
          type: string
          format: email
          example: john.doe@example.org
        gender:
          type: string
          example: m
          description: "m, f or o"
        language:
          type: string
          example: fr_ca
          description: "en_ca or fr_ca"
        joinedOn:
          type: [ 'string', 'null' ]
          example: "2014-12-09 13:42:48.020"
        updatedOn:
          type: [ 'string', 'null' ]
          example: "2014-12-10 12:41:42.020"
        consentType:
          type: string
          example: implied
        postalCode:
          type: string
          example: ""
        country:
          type: string
          example: CA
          description: ISO 3166-1 alpha-2 country code
        note:
          type: string
          example: ""
        birthdate:
          type: [ 'string', 'null' ]
          example: null
        mailingsReceived:
          type: integer
          example: 0
        mailingsOpened:
          type: integer
          example: 0
        mailingsClicked:
          type: integer
          example: 0
        customFields:
          type: object
          additionalProperties: true
          example:
            "1": "This is a test !"
            "2": 1000
            "3": 1.5
            "4": "2000-01-01"

    MemberInput:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          format: email
          example: testing@example.org
        gender:
          type: string
          example: m
          description: "m, f or o"
        groups:
          type: string
          example: "123,34565,56757,34"
          description: CSV list of group IDs to subscribe the member to
        firstname:
          type: string
          example: John
        lastname:
          type: string
          example: Doe
        company:
          type: string
          example: John Doe Company inc
        language:
          type: string
          example: en_ca
          description: "en_ca or fr_ca"
        birthdate:
          type: string
          example: "1980-12-04"
          description: Format Y-m-d
        postalCode:
          type: string
          example: h1h1h1
        country:
          type: string
          example: CA
          description: ISO 3166-1 alpha-2 country code
        note:
          type: string
          example: This is a test.
        customFields:
          type: object
          additionalProperties: true
          description: Keys are string IDs of custom fields. Values can be string, integer, or decimal number.
          example:
            "1": "this is a test!"
            "2": 200
            "3": 1.5
            "4": "2000-01-01"

    MemberPatchInput:
      type: object
      properties:
        email:
          type: string
          format: email
          example: testing@example.org
          description: The member's NEW email address
        gender:
          type: string
          example: f
          description: "m, f or o"
        firstname:
          type: string
          example: Janette
        lastname:
          type: string
          example: Doe
        company:
          type: string
          example: Doe Company inc
        language:
          type: string
          example: en_ca
          description: "en_ca or fr_ca"
        birthdate:
          type: string
          example: "1980-12-04"
          description: Format Y-m-d
        postalCode:
          type: string
          example: h1h1h1
        country:
          type: string
          example: CA
        note:
          type: string
          example: This is a test.
        customFields:
          type: object
          additionalProperties: true
          example:
            "1": "this is a test!"
            "2": 200
            "3": 1.5
            "4": "2000-01-01"

    BouncedMember:
      type: object
      properties:
        firstname:
          type: string
          example: ""
        lastname:
          type: string
          example: ""
        company:
          type: string
          example: ""
        email:
          type: string
          format: email
          example: hello2@example.org
        gender:
          type: string
          example: ""
        language:
          type: string
          example: ""
        joinedOn:
          type: string
          example: "2020-10-01 15:22:32.563"
        updatedOn:
          type: [ 'string', 'null' ]
          example: "2021-12-10 12:41:42.020"
        consentType:
          type: string
          example: implied
        postalCode:
          type: string
          example: ""
        country:
          type: string
          example: ""
        note:
          type: string
          example: ""
        birthdate:
          type: [ 'string', 'null' ]
          example: null
        hardBouncedOn:
          type: [ 'string', 'null' ]
          example: null
        customFields:
          type: object
          additionalProperties: true
          example:
            "1": "this is a test !"
            "2": 6544
            "3": 1.5
            "4": "2000-01-01"

    UnsubscribedMember:
      type: object
      properties:
        firstname:
          type: string
          example: John
        lastname:
          type: string
          example: Doe
        company:
          type: string
          example: John Doe Company inc
        email:
          type: string
          format: email
          example: john.doe@example.org
        gender:
          type: string
          example: m
        language:
          type: string
          example: en_ca
        joinedOn:
          type: string
          example: "2015-10-05 11:09:04.710"
        updatedOn:
          type: [ 'string', 'null' ]
          example: "2016-12-10 12:41:42.020"
        consentType:
          type: string
          example: implied
        postalCode:
          type: string
          example: "A0A 0A0"
        country:
          type: string
          example: CA
        note:
          type: string
          example: "He's awesome"
        birthdate:
          type: [ 'string', 'null' ]
          example: null
        unsubscribedOn:
          type: string
          example: "2015-10-05 11:09:04.710"
        customFields:
          type: object
          additionalProperties: true
          example:
            "1": "this is a test !"
            "2": 6544
            "3": 1.5
            "4": "2000-01-01"

    Group:
      type: object
      properties:
        id:
          type: integer
          example: 159872
        title:
          type: string
          example: Testing Group 1
        isPublic:
          type: boolean
          example: false
        membersCount:
          type: integer
          example: 12
        mailingsCount:
          type: integer
          example: 0
        createdOn:
          type: string
          example: "2014-12-09 13:48:44.887"
        isDynamic:
          type: boolean
          example: false

    GroupSummary:
      type: object
      properties:
        id:
          type: integer
          example: 159871
        title:
          type: string
          example: Testing_group1
        isPublic:
          type: boolean
          example: false
        createdOn:
          type: string
          example: "2014-12-09 13:36:18.367"
        isDynamic:
          type: boolean
          example: false

    GroupInput:
      type: object
      required:
        - title
        - isPublic
      properties:
        title:
          type: string
          description: The name of the group
          example: testing title for group
        isPublic:
          type: boolean
          description: "Should the group be a public group or not. See our documentation for the difference between the two types: https://support.cyberimpact.com/articles/63?l=en_ca#publicvsprivategroup"
          example: true

    GroupPatchInput:
      type: object
      properties:
        title:
          type: string
          description: The name of the group
          example: testing title Modification for group
        isPublic:
          type: boolean
          description: "Should the group be a public group or not. See our documentation for the difference between the two types: https://support.cyberimpact.com/articles/63?l=en_ca#publicvsprivategroup"
          example: true

    SentMailing:
      type: object
      properties:
        id:
          type: integer
          example: 603
        subject:
          type: string
          example: Test test test
        language:
          type: string
          example: en_ca
        startedOn:
          type: string
          example: "2010-06-04 14:20:40.217"
        recipientsCount:
          type: integer
          example: 2
        mailFrom:
          type: string
          example: ""

    ScheduledMailing:
      type: object
      properties:
        id:
          type: integer
          example: 2470
        subject:
          type: string
          example: "Test de l'API"
        language:
          type: string
          example: fr_ca
        scheduledOn:
          type: string
          example: "2020-10-31 08:20:00.000"
        recipientsCount:
          type: integer
          example: 9
        mailFrom:
          type: string
          example: admin@example.org

    ArchivedMailing:
      type: object
      properties:
        id:
          type: integer
          example: 603
        subject:
          type: string
          example: Test test test
        language:
          type: string
          example: en_ca
        startedOn:
          type: string
          example: "2010-06-04 14:20:40.217"
        recipientsCount:
          type: integer
          example: 2
        mailFrom:
          type: string
          example: ""
        archivedOn:
          type: string
          example: "2010-09-01 10:33:15.000"

    MailingDetail:
      type: object
      properties:
        id:
          type: integer
          example: 2481
        subject:
          type: string
          example: API Testing
        language:
          type: string
          example: en_ca
        startedOn:
          type: [ 'string', 'null' ]
          example: null
        scheduledOn:
          type: [ 'string', 'null' ]
          example: "2015-10-14 08:58:33.000"
        replyTo:
          type: string
          example: info@example.org
        bodyHtml:
          type: string
          example: "<a href=\"http://example.org\">Hello world</a>..."
        bodyText:
          type: string
          example: "Hello world !!!"
        recipientsCount:
          type: integer
          example: 0
        emailsSent:
          type: integer
          example: 2
        emailsDelivered:
          type: integer
          example: 2
        emailsStopped:
          type: integer
          example: 0
        views:
          type: integer
          example: 1
        clicks:
          type: integer
          example: 1
        sentToFriend:
          type: integer
          example: 1
        incorrectAddresses:
          type: integer
          example: 0
        technicalProblems:
          type: integer
          example: 0
        deliveryRate:
          type: number
          example: 0
        clickRate:
          type: number
          example: 0.5
        viewRate:
          type: number
          example: 0.5
        status:
          type: string
          example: sent
        mailFrom:
          type: string
          example: admin@example.org
        fromName:
          type: string
          example: John Doe
        mailingStatistics:
          type: string
          example: detailed
        links:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
                example: 6899
              url:
                type: string
                example: https://example.org
              clicksUnique:
                type: integer
                example: 0
              clicksTotal:
                type: integer
                example: 0
        recipientGroups:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
                example: 159854
              title:
                type: string
                example: Testing group
        viewOnlineURL:
          type: string
          example: http://example.org

    MailingInput:
      type: object
      required:
        - subject
        - language
        - groups
        - sendAt
      properties:
        subject:
          type: string
          example: This is a test mailing
        language:
          type: string
          example: en_ca
          description: "en_ca or fr_ca"
        groups:
          type: string
          example: "159868,171416"
          description: CSV list of group IDs to send the mailing to
        sendAt:
          type: string
          example: "2015-10-27 14:00:00"
          description: "Date and time to start sending. Format: yyyy-mm-dd HH:mm:ss"
        replyTo:
          type: string
          example: info@example.org
        fromName:
          type: string
          example: testing department
        mailFrom:
          type: string
          example: info@example.org
          description: "The email address to put as From: for the mailing. This must be a [validated sender email address](https://faq.cyberimpact.com/en/articles/126) in your account."
        bodyHtml:
          type: string
          example: "<b>Testing!</b>"
          description: HTML body. At least one of bodyHtml or bodyText is required.
        bodyText:
          type: string
          example: "Testing!"
          description: Plain text body. At least one of bodyHtml or bodyText is required.
        googleAnalytics:
          type: boolean
          example: true
        googleAnalyticsCampaign:
          type: string
          example: testing campaign 2015
        mailingStatistics:
          type: string
          enum:
            - detailed
            - anonymized
          example: detailed
          description: "'detailed' (default) or 'anonymized' to anonymize click/open statistics"
        updateProfileForm:
          type: number
          example: 32
          description: Update profile form ID to include at the bottom of the mailing

    RecipientMember:
      type: object
      properties:
        idMember:
          type: [ 'integer', 'null' ]
          example: 1
        email:
          type: string
          format: email
          example: testing.tester@example.net
        firstname:
          type: string
          example: John
        lastname:
          type: string
          example: Doe
        company:
          type: string
          example: ""
        gender:
          type: string
          example: ""
        language:
          type: string
          example: ""
        joinedOn:
          type: string
          example: "2020-10-01 15:17:56.403"
        updatedOn:
          type: [ 'string', 'null' ]
          example: "2021-12-10 12:41:42.020"
        consentType:
          type: string
          example: implied
        birthdate:
          type: [ 'string', 'null' ]
          example: null
        postalCode:
          type: string
          example: ""
        country:
          type: string
          example: CA
        note:
          type: string
          example: ""
        customFields:
          type: object
          additionalProperties: true
          example:
            "1": "this is a test!"
            "2": 200
            "3": 1.5
            "4": "2000-01-01"

    Template:
      type: object
      properties:
        id:
          type: integer
          example: 1405
        title:
          type: string
          example: blablabla
        createdOn:
          type: string
          example: "2014-11-10 14:43:10.103"
        updatedOn:
          type: string
          example: "2014-11-10 14:43:10.103"

    TemplateDetail:
      type: object
      properties:
        id:
          type: integer
          example: 1419
        title:
          type: string
          example: ""
        bodyHtml:
          type: string
          example: "<b>Testing !</b><p>this is just a test</p>"
        bodyText:
          type: string
          example: "This is a test!"
        createdOn:
          type: string
          example: "2014-11-10 15:38:38.827"
        updatedOn:
          type: string
          example: "2014-11-10 15:38:38.827"

    TemplateInput:
      type: object
      required:
        - title
      properties:
        title:
          type: string
          example: This is a test template
        bodyHtml:
          type: string
          example: "<b>Testing!</b>"
          description: HTML body. At least one of bodyHtml or bodyText is required.
        bodyText:
          type: string
          example: "Testing!"
          description: Plain text body. At least one of bodyHtml or bodyText is required.

    Batch:
      type: object
      properties:
        id:
          type: integer
          example: 176
        batchType:
          type: string
          example: unsubscribe
        batchJson:
          type: object
          additionalProperties: true
          example:
            batchType: unsubscribe
            ids: [ 1, 2, 3 ]
        createdOn:
          type: string
          example: "2015-10-28 11:55:56.217"
        status:
          type: string
          example: "NEW"
          description: "NEW, PROCESSING, or COMPLETED"
        result:
          type: [ 'object', 'null' ]
          properties:
            errors:
              type: array
              items:
                type: object
                properties:
                  id:
                    oneOf:
                      - type: string
                      - type: integer
                  description:
                    type: string
            successes:
              type: array
              items:
                type: string
          example: null

    ConsentDetails:
      type: object
      properties:
        consentType:
          type: string
          example: implied
        relationType:
          type: string
          example: active-clients
        consentDate:
          type: [ 'string', 'null' ]
          example: "2022-01-01 00:00:00.000"
        consentExpiration:
          type: [ 'string', 'null' ]
          example: "2024-01-01 00:00:00.000"
        consentProof:
          type: string
          example: "Customer since 2015, see invoices"

    ConsentInput:
      type: object
      required:
        - relationType
      properties:
        relationType:
          type: string
          example: active-clients
          description: >
            Accepted values: express-consent, active-clients, information-request,
            business-card, web-contacts, purchased-list, contest-participants,
            mixed-list, association-members, employees, partners, inactive-clients
          enum:
            - express-consent
            - active-clients
            - information-request
            - business-card
            - web-contacts
            - purchased-list
            - contest-participants
            - mixed-list
            - association-members
            - employees
            - partners
            - inactive-clients
        consentDate:
          type: [ 'string', 'null' ]
          example: "2022-01-01"
          description: Format Y-m-d
        consentProof:
          type: string
          example: "Customer since 2015, see invoices"

    CustomField:
      type: object
      properties:
        id:
          type: integer
          example: 1
        name:
          type: string
          example: Favorite colour
        type:
          type: string
          example: text
          description: "text, date, integer, or decimal number"

    Token:
      type: object
      properties:
        tokenUniqueId:
          type: string
          example: thisIsTheUniqueKeyOfTheToken
        token:
          type: string
          example: ThisIsTheTokenContent
        expiration:
          type: string
          example: "2032-01-01 12:34:56"

tags:
  - name: General
    description: General utility endpoints
  - name: Members
    description: Manage contacts (members) in your account
  - name: Groups
    description: Manage groups in your account
  - name: Mailings
    description: Manage and send mailings
  - name: Templates
    description: Manage email templates
  - name: Batches
    description: Batch process large numbers of member operations
  - name: Tokens
    description: Manage API tokens. Please note that token modification via PATCH is not supported.

paths:
  /ping:
    get:
      tags:
        - General
      summary: Ping
      description: Simple function to verify your connection with the API.
      operationId: getPing
      responses:
        "200":
          description: Successful ping response
          content:
            application/json:
              schema:
                type: object
                properties:
                  ping:
                    type: string
                    example: success
                  username:
                    type: string
                    example: yourUsername
                  email:
                    type: string
                    format: email
                    example: yourEmail@example.org
                  account:
                    type: string
                    example: Your account name
              example:
                ping: success
                username: yourUsername
                email: yourEmail@example.org
                account: Your account name
        "401":
          description: Unauthorized — invalid or missing token

  /members:
    get:
      tags:
        - Members
      summary: Retrieve members
      description: |
        Retrieve a paginated list of your members.

        Active members are subscribed members that are part of group(s).
        Orphan members are subscribed members that are not part of a group.

        Note: The returned property `items_per_page` is deprecated and will eventually be removed. Use `limit` instead.
      operationId: getMembers
      parameters:
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: status
          in: query
          description: The status of the member in your account
          schema:
            type: string
            default: active
            enum:
              - active
              - orphans
              - all
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - consent_type_asc
              - consent_type_desc
              - consent_date_asc
              - consent_date_desc
              - updated_asc
              - updated_desc
        - name: joinedOnFrom
          in: query
          description: "Date (start of day) from which members were added (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: joinedOnTo
          in: query
          description: "Date (end of day) to which members were added (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: updatedOnFrom
          in: query
          description: "Date (start of day) from which members were last updated (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: updatedOnTo
          in: query
          description: "Date (end of day) to which members were last updated (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Paginated list of members
          content:
            application/json:
              schema:
                type: object
                properties:
                  members:
                    type: array
                    items:
                      $ref: "#/components/schemas/Member"
                  totalCount:
                    type: integer
                    example: 304711
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 2
                  items_per_page:
                    type: integer
                    example: 2
                    deprecated: true
                    description: Deprecated — use limit instead
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized

    post:
      tags:
        - Members
      summary: Add a new member
      description: |
        Add a new member in your account. If you need the member to confirm their subscription, it is
        recommended that you use the opt-in endpoint instead.

        If you use this method in an online form, it is **strongly recommended** to add a CAPTCHA to
        avoid abuse.

        Warning: This method is throttled. If you wish to use it for synchronization purposes between
        two systems, please contact us. If you need to add multiple members at once, use the batches endpoint.
      operationId: createMember
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MemberInput"
            example:
              email: testing@example.org
              gender: m
              groups: "123,34565,56757,34"
              firstname: John
              lastname: Doe
              company: John Doe Company inc
              language: en_ca
              birthdate: "1980-12-04"
              postalCode: h1h1h1
              country: CA
              note: This is a test.
              customFields:
                "1": "this is a test!"
                "2": 200
                "3": 1.5
                "4": "2000-01-01"
      responses:
        "201":
          description: Attributes of the newly created member
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Member"
              example:
                id: 3972571
                firstname: John
                lastname: Doe
                company: John Doe Company inc
                email: testing@example.org
                gender: m
                language: en_ca
                joinedOn: "2015-10-26 10:14:17.653"
                updatedOn: null
                consentType: implied
                postalCode: h1h1h1
                country: CA
                note: This is a test.
                birthdate: "1980-12-04"
                mailingsReceived: 0
                mailingsOpened: 0
                mailingsClicked: 0
                customFields:
                  "1": "this is a test!"
                  "2": 200
                  "3": 1.5
                  "4": "2000-01-01"
        "400":
          description: Bad request
        "401":
          description: Unauthorized

  /members/{key}:
    get:
      tags:
        - Members
      summary: Retrieve a specific member
      description: Retrieve a specific member based on their key.
      operationId: getMember
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
      responses:
        "200":
          description: All attributes of the specified member
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Member"
              example:
                id: 3664823
                firstname: John
                lastname: Doe
                company: John Doe Company inc
                email: john.doe@example.org
                gender: m
                language: fr_ca
                joinedOn: "2014-12-09 13:42:48.020"
                updatedOn: "2015-12-10 12:41:42.020"
                consentType: implied
                postalCode: ""
                country: ""
                note: ""
                birthdate: null
                mailingsReceived: 0
                mailingsOpened: 0
                mailingsClicked: 0
                customFields:
                  "1": "This is a test !"
                  "2": 1000
                  "3": 1.5
                  "4": "2000-01-01"
        "401":
          description: Unauthorized
        "404":
          description: Member not found

    put:
      tags:
        - Members
      summary: Replace a member
      description: |
        Modify the representation of a member so that it becomes completely as specified.
        Unspecified attributes will be reset to their default empty values.
      operationId: replaceMember
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - email
              properties:
                email:
                  type: string
                  format: email
                  example: testing@example.org
                  description: The member's NEW email address
                gender:
                  type: string
                  example: f
                  description: "m, f or o"
                firstname:
                  type: string
                  example: Jane
                lastname:
                  type: string
                  example: Doe
                company:
                  type: string
                  example: Jane Doe Company inc
                language:
                  type: string
                  example: en_ca
                  description: "en_ca or fr_ca"
                birthdate:
                  type: string
                  example: "1980-12-04"
                  description: Format Y-m-d
                postalCode:
                  type: string
                  example: h1h1h1
                country:
                  type: string
                  example: CA
                note:
                  type: string
                  example: This is a test.
                customFields:
                  type: object
                  additionalProperties: true
                  example:
                    "1": "this is a test!"
                    "2": 200
                    "3": 1.5
                    "4": "2000-01-01"
            example:
              email: testing@example.org
              gender: f
              firstname: Jane
              lastname: Doe
              company: Jane Doe Company inc
              language: en_ca
              birthdate: "1980-12-04"
              postalCode: h1h1h1
              country: CA
              note: This is a test.
              customFields:
                "1": "this is a test!"
                "2": 200
                "3": 1.5
                "4": "2000-01-01"
      responses:
        "200":
          description: Attributes of the replaced member
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Member"
              example:
                id: 3972571
                firstname: Jane
                lastname: Doe
                company: Jane Doe Company inc
                email: testing@example.org
                gender: f
                language: en_ca
                joinedOn: "2015-10-26 10:14:17.653"
                updatedOn: "2016-12-10 12:41:42.020"
                consentType: implied
                postalCode: h1h1h1
                country: CA
                note: This is a test.
                birthdate: "1980-12-04"
                mailingsReceived: 0
                mailingsOpened: 0
                mailingsClicked: 0
                customFields:
                  "1": "this is a test!"
                  "2": 200
                  "3": 1.5
                  "4": "2000-01-01"
        "400":
          description: Bad request
        "401":
          description: Unauthorized
        "404":
          description: Member not found

    patch:
      tags:
        - Members
      summary: Edit a member
      description: |
        Modify the representation of a member by changing only the specified attributes.
        Unspecified attributes are left untouched.
      operationId: editMember
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MemberPatchInput"
            example:
              gender: f
              firstname: Janette
      responses:
        "200":
          description: Attributes of the edited member
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Member"
              example:
                id: 3972571
                firstname: Janette
                lastname: Doe
                company: Janette Doe Company inc
                email: testing@example.org
                gender: f
                language: en_ca
                joinedOn: "2015-10-26 10:14:17.653"
                updatedOn: "2016-12-10 12:41:42.020"
                consentType: implied
                postalCode: h1h1h1
                country: CA
                note: This is a test.
                birthdate: "1980-12-04"
                mailingsReceived: 0
                mailingsOpened: 0
                mailingsClicked: 0
                customFields:
                  "1": "blablabla..."
                  "2": 200
                  "3": 1.5
                  "4": "2000-01-01"
        "400":
          description: Bad request
        "401":
          description: Unauthorized
        "404":
          description: Member not found

    delete:
      tags:
        - Members
      summary: Delete a member
      description: Delete a specific member based on their key.
      operationId: deleteMember
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
      responses:
        "200":
          description: The key of the member and its deletion status
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
              example:
                "testing@example.org": deleted
        "401":
          description: Unauthorized
        "404":
          description: Member not found

  /members/bounced:
    get:
      tags:
        - Members
      summary: Retrieve bounced members
      description: Retrieve a paginated list of members for which a hard bounce was received for the last mailing sent to them.
      operationId: getBouncedMembers
      parameters:
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
        - name: bouncedOnFrom
          in: query
          description: "Date (start of day) from which members have bounced (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: bouncedOnTo
          in: query
          description: "Date (end of day) to which members have bounced (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: updatedOnFrom
          in: query
          description: "Date (start of day) from which members were last updated (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: updatedOnTo
          in: query
          description: "Date (end of day) to which members were last updated (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Paginated list of bounced members
          content:
            application/json:
              schema:
                type: object
                properties:
                  members:
                    type: array
                    items:
                      $ref: "#/components/schemas/BouncedMember"
                  totalCount:
                    type: integer
                    example: 1008
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 2
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized

  /members/unsubscribed:
    get:
      tags:
        - Members
      summary: Retrieve unsubscribed members
      description: Retrieve a paginated list of members who unsubscribed from your mailings.
      operationId: getUnsubscribedMembers
      parameters:
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
        - name: unsubscribedOnFrom
          in: query
          description: "Date (start of day) from which members unsubscribed (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: unsubscribedOnTo
          in: query
          description: "Date (end of day) to which members unsubscribed (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: updatedOnFrom
          in: query
          description: "Date (start of day) from which members were last updated (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: updatedOnTo
          in: query
          description: "Date (end of day) to which members were last updated (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Paginated list of unsubscribed members
          content:
            application/json:
              schema:
                type: object
                properties:
                  members:
                    type: array
                    items:
                      $ref: "#/components/schemas/UnsubscribedMember"
                  totalCount:
                    type: integer
                    example: 215
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 2
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized

  /members/unsubscribed/{email}:
    get:
      tags:
        - Members
      summary: Retrieve a specific unsubscribed member
      description: Retrieve a specific unsubscribed member based on their email address.
      operationId: getUnsubscribedMember
      parameters:
        - name: email
          in: path
          required: true
          description: The unsubscribed member's email address
          schema:
            type: string
            format: email
      responses:
        "200":
          description: The unsubscribed member's details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UnsubscribedMember"
        "401":
          description: Unauthorized
        "404":
          description: Member not found

    post:
      tags:
        - Members
      summary: Unsubscribe a member
      description: |
        Unsubscribe a member based on their key.
        The field `isNewUnsubscription` indicates whether the unsubscription was new or the member was already unsubscribed.
      operationId: unsubscribeMember
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
      responses:
        "200":
          description: The unsubscribed member's details including whether this was a new unsubscription
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/UnsubscribedMember"
                  - type: object
                    properties:
                      isNewUnsubscription:
                        type: boolean
                        example: true
              example:
                firstname: ""
                lastname: ""
                company: ""
                email: john.doe@cyberimpact.com
                gender: ""
                language: ""
                joinedOn: "2015-11-10 15:48:24.873"
                updatedOn: "2016-12-10 12:41:42.020"
                consentType: implied
                postalCode: ""
                country: ""
                note: ""
                birthdate: null
                unsubscribedOn: "2015-11-10 15:48:24.873"
                customFields:
                  "1": "this is a test !"
                  "2": 6544
                  "3": 1.5
                  "4": "2000-01-01"
                isNewUnsubscription: true
        "401":
          description: Unauthorized
        "404":
          description: Member not found

  /members/{key}/groups:
    get:
      tags:
        - Members
      summary: Retrieve member's groups
      description: Retrieve a paginated list of the groups that the specified member is part of.
      operationId: getMemberGroups
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - title_asc
              - title_desc
              - created_asc
              - created_desc
      responses:
        "200":
          description: Paginated list of the member's groups
          content:
            application/json:
              schema:
                type: object
                properties:
                  groups:
                    type: array
                    items:
                      $ref: "#/components/schemas/GroupSummary"
                  totalCount:
                    type: integer
                    example: 2
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized
        "404":
          description: Member not found

    post:
      tags:
        - Members
      summary: Add groups to member
      description: Make the specified member part of the specified groups.
      operationId: addMemberGroups
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groups:
                  type: string
                  example: "159871,159873"
                  description: CSV list of group IDs to add the member to
            example:
              groups: "159871,159873"
      responses:
        "200":
          description: List of the member's subscriptions after the update
          content:
            application/json:
              schema:
                type: object
                properties:
                  groups:
                    type: array
                    items:
                      $ref: "#/components/schemas/GroupSummary"
              example:
                groups:
                  - id: 159871
                    title: Testing_group1
                    isPublic: false
                    createdOn: "2015-12-09 13:36:18.367"
                    isDynamic: false
                  - id: 159873
                    title: group test api 1
                    isPublic: false
                    createdOn: "2015-12-09 13:49:24.460"
                    isDynamic: false
                  - id: 171416
                    title: Testing_group2
                    isPublic: false
                    createdOn: "2012-05-04 13:51:18.800"
                    isDynamic: false
                  - id: 159878
                    title: group test api 2
                    isPublic: false
                    createdOn: "2011-12-19 13:23:21.277"
                    isDynamic: false
        "401":
          description: Unauthorized
        "404":
          description: Member not found

    put:
      tags:
        - Members
      summary: Replace member's groups
      description: Replace completely the list of groups that a member is part of with the ones specified.
      operationId: replaceMemberGroups
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groups:
                  type: string
                  example: "171415,159877"
                  description: CSV list of group IDs the member will belong to
            example:
              groups: "171415,159877"
      responses:
        "200":
          description: The complete updated list of the member's groups
          content:
            application/json:
              schema:
                type: object
                properties:
                  groups:
                    type: array
                    items:
                      $ref: "#/components/schemas/GroupSummary"
              example:
                groups:
                  - id: 171415
                    title: another testing group
                    isPublic: false
                    createdOn: "2015-05-04 13:51:17.020"
                    isDynamic: false
                  - id: 159877
                    title: autre groupe de test
                    isPublic: true
                    createdOn: "2014-12-11 15:22:22.377"
                    isDynamic: false
        "401":
          description: Unauthorized
        "404":
          description: Member not found

  /members/{key}/mailings:
    get:
      tags:
        - Members
      summary: Retrieve member's received mailings
      description: Retrieve a paginated list of the member's received mailings.
      operationId: getMemberMailings
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - date_sent_asc
              - date_sent_desc
              - date_opened_asc
              - date_opened_desc
      responses:
        "200":
          description: Paginated list of the member's received mailings
          content:
            application/json:
              schema:
                type: object
                properties:
                  mailings:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          example: 1
                        subject:
                          type: string
                          example: yo
                        language:
                          type: string
                          example: fr_ca
                        startedOn:
                          type: string
                          example: "2022-03-16 16:45:02.570"
                        sentOn:
                          type: string
                          example: "2022-03-16 16:44:57.600"
                        opened:
                          type: boolean
                          example: true
                        openedOn:
                          type: [ 'string', 'null' ]
                          example: "2022-03-16 18:37:24.600"
                  totalCount:
                    type: integer
                    example: 1
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized
        "404":
          description: Member not found

  /members/{key}/groups/{groupId}:
    delete:
      tags:
        - Members
      summary: Remove member from a group
      description: Remove the specified member from the specified group.
      operationId: removeMemberFromGroup
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
        - name: groupId
          in: path
          required: true
          description: Numerical ID of the group to remove from the member's groups list
          schema:
            type: integer
      responses:
        "200":
          description: Status of the removal from the specified group
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
              example:
                "171415": deleted
        "401":
          description: Unauthorized
        "404":
          description: Member or group not found

  /members/optins:
    post:
      tags:
        - Members
      summary: Opt-in a member
      description: |
        Send an opt-in email to the specified email address, creating the member if not already existing
        and adding them to the specified list of groups.

        Warning: This method is throttled. If you use it in an online form, it is **strongly recommended**
        to add a CAPTCHA to avoid abuse.
      operationId: optinMember
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - email
                - groups
              properties:
                email:
                  type: string
                  format: email
                  example: testing@example.org
                gender:
                  type: string
                  example: f
                  description: "m, f or o"
                groups:
                  type: string
                  example: "2554,65458,211238"
                  description: CSV list of group IDs the member will be added to
                firstname:
                  type: string
                  example: Jane
                lastname:
                  type: string
                  example: Doe
                company:
                  type: string
                  example: Jane Doe Company inc
                language:
                  type: string
                  example: en_ca
                  description: "en_ca or fr_ca"
                birthdate:
                  type: string
                  example: "1980-12-04"
                  description: Format Y-m-d
                postalCode:
                  type: string
                  example: h1h1h1
                country:
                  type: string
                  example: CA
                note:
                  type: string
                  example: This is a test.
                optinConfirmUrl:
                  type: string
                  example: "http://www.example.com"
                  description: "URL used as the opt-in confirmation page (format: http://www.example.com)"
                customFields:
                  type: object
                  additionalProperties: true
                  example:
                    "1": "this is a test!"
                    "2": 200
                    "3": 1.5
                    "4": "2000-01-01"
            example:
              email: testing@example.org
              gender: f
              groups: "2554,65458,211238"
              firstname: Jane
              lastname: Doe
              company: Jane Doe Company inc
              language: en_ca
              birthdate: "1980-12-04"
              postalCode: h1h1h1
              country: CA
              note: This is a test.
              customFields:
                "1": "this is a test!"
                "2": 200
                "3": 1.5
                "4": "2000-01-01"
      responses:
        "201":
          description: The ID of the opt-in request and its status
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
              example:
                "555": created
        "400":
          description: Bad request
        "401":
          description: Unauthorized

  /members/{key}/consent:
    get:
      tags:
        - Members
      summary: Retrieve a specific member's consent details
      description: Retrieve more consent information for a specific member based on their key.
      operationId: getMemberConsent
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
      responses:
        "200":
          description: List of the consent attributes for the specified member
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConsentDetails"
              example:
                consentType: implied
                relationType: active-clients
                consentDate: "2022-01-01 00:00:00.000"
                consentExpiration: "2024-01-01 00:00:00.000"
                consentProof: "Customer since 2015, see invoices"
        "401":
          description: Unauthorized
        "404":
          description: Member not found

    put:
      tags:
        - Members
      summary: Set consent for a specific member
      description: |
        Set consent for a specific member based on their key.
        Note: Some consent types cannot be overridden — this method returns a 422 status code with a message when that happens.
      operationId: setMemberConsent
      parameters:
        - name: key
          in: path
          required: true
          description: Can be either the member's email address or their numerical ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ConsentInput"
            example:
              relationType: active-clients
              consentDate: "2022-01-01"
              consentProof: "Customer since 2015, see invoices"
      responses:
        "200":
          description: The new consent attributes for the specified member
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConsentDetails"
              example:
                consentType: implied
                relationType: active-clients
                consentDate: "2022-01-01 00:00:00.000"
                consentExpiration: "2024-01-01 00:00:00.000"
                consentProof: "Customer since 2015, see invoices"
        "400":
          description: Bad request
        "401":
          description: Unauthorized
        "404":
          description: Member not found
        "422":
          description: Unprocessable entity — consent cannot be overridden

  /customfields:
    get:
      tags:
        - Members
      summary: Retrieve account custom fields list
      description: |
        List of custom fields set in your account. Field type can be one of:
        - text
        - date
        - integer
        - decimal number
      operationId: getCustomFields
      responses:
        "200":
          description: List of custom fields defined in the account
          content:
            application/json:
              schema:
                type: object
                properties:
                  customFields:
                    type: array
                    items:
                      $ref: "#/components/schemas/CustomField"
              example:
                customFields:
                  - id: 1
                    name: Favorite colour
                    type: text
                  - id: 2
                    name: Random date
                    type: date
                  - id: 3
                    name: Number of cats
                    type: integer
                  - id: 4
                    name: Last order amount
                    type: decimal number
        "401":
          description: Unauthorized

  /groups:
    get:
      tags:
        - Groups
      summary: Retrieve groups
      description: Retrieve a paginated list of groups.
      operationId: getGroups
      parameters:
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - group_asc
              - group_desc
              - nbmember_asc
              - nbmember_desc
              - type_asc
              - type_desc
              - nbnewsletter_asc
              - nbnewsletter_desc
              - date_asc
              - date_desc
      responses:
        "200":
          description: Paginated list of groups
          content:
            application/json:
              schema:
                type: object
                properties:
                  groups:
                    type: array
                    items:
                      $ref: "#/components/schemas/Group"
                  totalCount:
                    type: integer
                    example: 94
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 2
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized

    post:
      tags:
        - Groups
      summary: Add a new group
      description: Add a new static group in your account.
      operationId: createGroup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GroupInput"
            example:
              title: testing title for group
              isPublic: true
      responses:
        "201":
          description: The newly created group
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Group"
              example:
                id: 171908
                title: testing title for group
                isPublic: true
                membersCount: 0
                mailingsCount: 0
                createdOn: "2015-10-26 16:14:01.337"
                isDynamic: false
        "400":
          description: Bad request
        "401":
          description: Unauthorized

  /groups/{id}:
    get:
      tags:
        - Groups
      summary: Retrieve group
      description: Retrieve a specific group based on its ID.
      operationId: getGroup
      parameters:
        - name: id
          in: path
          required: true
          description: The group's numerical ID
          schema:
            type: integer
      responses:
        "200":
          description: The group details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Group"
              example:
                id: 171423
                title: group test api 1
                isPublic: false
                membersCount: 1
                mailingsCount: 0
                createdOn: "2015-08-28 11:36:19.020"
                isDynamic: false
        "401":
          description: Unauthorized
        "404":
          description: Group not found

    put:
      tags:
        - Groups
      summary: Replace a group
      description: |
        Modify the representation of a group so that it becomes completely as specified.
        Unspecified attributes will be reset to their default empty values.
        Note: Replacing a dynamic group is not possible from the API.
      operationId: replaceGroup
      parameters:
        - name: id
          in: path
          required: true
          description: The group's numerical ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GroupInput"
            example:
              title: testing title replacement for group
              isPublic: true
      responses:
        "200":
          description: The modified group
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Group"
              example:
                id: 171423
                title: testing title replacement for group
                isPublic: true
                membersCount: 1
                mailingsCount: 0
                createdOn: "2015-08-28 11:36:19.020"
                isDynamic: false
        "400":
          description: Bad request
        "401":
          description: Unauthorized
        "404":
          description: Group not found

    patch:
      tags:
        - Groups
      summary: Edit a group
      description: |
        Modify the representation of a group by changing only the specified attributes.
        Unspecified attributes are left untouched.
        Note: Editing a dynamic group is not possible from the API.
      operationId: editGroup
      parameters:
        - name: id
          in: path
          required: true
          description: The group's numerical ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GroupPatchInput"
            example:
              title: testing title Modification for group
      responses:
        "200":
          description: The modified group
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Group"
              example:
                id: 171423
                title: testing title modification for group
                isPublic: true
                membersCount: 1
                mailingsCount: 0
                createdOn: "2015-08-28 11:36:19.020"
                isDynamic: false
        "400":
          description: Bad request
        "401":
          description: Unauthorized
        "404":
          description: Group not found

    delete:
      tags:
        - Groups
      summary: Delete a group
      description: Delete a specific group based on its ID.
      operationId: deleteGroup
      parameters:
        - name: id
          in: path
          required: true
          description: The group's numerical ID
          schema:
            type: integer
      responses:
        "200":
          description: The ID of the group and its deletion status
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
              example:
                "171423": deleted
        "401":
          description: Unauthorized
        "404":
          description: Group not found

  /groups/{id}/members:
    get:
      tags:
        - Groups
      summary: Retrieve group members
      description: Retrieve a paginated list of all the members in the specified group.
      operationId: getGroupMembers
      parameters:
        - name: id
          in: path
          required: true
          description: The group's numerical ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - consent_type_asc
              - consent_type_desc
              - consent_date_asc
              - consent_date_desc
              - updated_asc
              - updated_desc
        - name: joinedOnFrom
          in: query
          description: "Date (start of day) from which members were added (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: joinedOnTo
          in: query
          description: "Date (end of day) to which members were added (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: updatedOnFrom
          in: query
          description: "Date (start of day) from which members were last updated (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
        - name: updatedOnTo
          in: query
          description: "Date (end of day) to which members were last updated (format: yyyy-mm-dd)"
          schema:
            type: string
            format: date
      responses:
        "200":
          description: Paginated list of group members
          content:
            application/json:
              schema:
                type: object
                properties:
                  members:
                    type: array
                    items:
                      $ref: "#/components/schemas/Member"
                  totalCount:
                    type: integer
                    example: 1
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized
        "404":
          description: Group not found

    delete:
      tags:
        - Groups
      summary: Remove all members from group
      description: Remove all members from a specific group.
      operationId: removeAllGroupMembers
      parameters:
        - name: id
          in: path
          required: true
          description: The group's numerical ID
          schema:
            type: integer
      responses:
        "200":
          description: Empty members list confirming all members have been removed
          content:
            application/json:
              schema:
                type: object
                properties:
                  members:
                    type: array
                    items: { }
              example:
                members: [ ]
        "401":
          description: Unauthorized
        "404":
          description: Group not found

  /mailings/sent:
    get:
      tags:
        - Mailings
      summary: Retrieve sent mailings
      description: |
        Retrieve a paginated list of all sent mailings.
        Note: This does not include any archived mailings.
      operationId: getSentMailings
      parameters:
        - name: idGroup
          in: query
          description: Filter to only show mailings sent to the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - language_asc
              - language_desc
              - subject_asc
              - subject_desc
              - recipients_asc
              - recipients_desc
              - date_asc
              - date_desc
      responses:
        "200":
          description: Paginated list of sent mailings
          content:
            application/json:
              schema:
                type: object
                properties:
                  mailings:
                    type: array
                    items:
                      $ref: "#/components/schemas/SentMailing"
                  totalCount:
                    type: integer
                    example: 793
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 2
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized

  /mailings/scheduled:
    get:
      tags:
        - Mailings
      summary: Retrieve scheduled mailings
      description: Retrieve a paginated list of all scheduled mailings.
      operationId: getScheduledMailings
      parameters:
        - name: idGroup
          in: query
          description: Filter to only show mailings scheduled to be sent to the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - language_asc
              - language_desc
              - subject_asc
              - subject_desc
              - recipients_asc
              - recipients_desc
              - date_asc
              - date_desc
      responses:
        "200":
          description: Paginated list of scheduled mailings
          content:
            application/json:
              schema:
                type: object
                properties:
                  mailings:
                    type: array
                    items:
                      $ref: "#/components/schemas/ScheduledMailing"
                  totalCount:
                    type: integer
                    example: 28
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 2
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized

  /mailings/archived:
    get:
      tags:
        - Mailings
      summary: Retrieve archived mailings
      description: Retrieve a paginated list of archived mailings.
      operationId: getArchivedMailings
      parameters:
        - name: idGroup
          in: query
          description: Filter to only show mailings sent to the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - language_asc
              - language_desc
              - subject_asc
              - subject_desc
              - recipients_asc
              - recipients_desc
              - date_asc
              - date_desc
              - date_sent_asc
              - date_sent_desc
      responses:
        "200":
          description: Paginated list of archived mailings
          content:
            application/json:
              schema:
                type: object
                properties:
                  mailings:
                    type: array
                    items:
                      $ref: "#/components/schemas/ArchivedMailing"
                  totalCount:
                    type: integer
                    example: 793
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 2
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized

  /mailings/{id}:
    get:
      tags:
        - Mailings
      summary: Retrieve a mailing
      description: Retrieve a specific mailing based on its ID.
      operationId: getMailing
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
      responses:
        "200":
          description: The mailing representation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MailingDetail"
              example:
                id: 2481
                subject: API Testing
                language: en_ca
                startedOn: null
                scheduledOn: "2015-10-14 08:58:33.000"
                replyTo: info@example.org
                bodyHtml: "<a href=\"http://example.org\">Hello world</a>..."
                bodyText: "Hello world !!!"
                recipientsCount: 0
                emailsSent: 2
                emailsDelivered: 2
                emailsStopped: 0
                views: 1
                clicks: 1
                sentToFriend: 1
                incorrectAddresses: 0
                technicalProblems: 0
                deliveryRate: 0
                clickRate: 0.5
                viewRate: 0.5
                status: sent
                mailFrom: admin@example.org
                fromName: John Doe
                mailingStatistics: detailed
                links:
                  - id: 6899
                    url: https://example.org
                    clicksUnique: 0
                    clicksTotal: 0
                recipientGroups:
                  - id: 159854
                    title: Testing group
                viewOnlineURL: http://example.org
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

    delete:
      tags:
        - Mailings
      summary: Delete a mailing
      description: Delete a specific mailing based on its ID (only if it has not already been sent).
      operationId: deleteMailing
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
      responses:
        "200":
          description: The ID of the mailing and its deletion status
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
              example:
                "2532": deleted
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

  /mailings:
    post:
      tags:
        - Mailings
      summary: Create a new mailing
      description: Create a new mailing scheduled to be sent.
      operationId: createMailing
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MailingInput"
            example:
              subject: This is a test mailing
              language: en_ca
              groups: "159868,171416"
              sendAt: "2015-10-27 14:00:00"
              replyTo: info@example.org
              fromName: testing department
              mailFrom: info@example.org
              bodyHtml: "<b>Testing!</b>"
              bodyText: "Testing!"
              googleAnalytics: true
              googleAnalyticsCampaign: testing campaign 2015
              mailingStatistics: detailed
              updateProfileForm: 32
      responses:
        "201":
          description: The mailing representation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MailingDetail"
              example:
                id: 2559
                subject: This is a test mailing
                language: en_ca
                startedOn: null
                scheduledOn: "2015-10-27 14:00:00"
                replyTo: info@example.org
                bodyHtml: "<b>Testing!</b>"
                bodyText: "Testing!"
                recipientsCount: 0
                emailsSent: 0
                emailsDelivered: 0
                views: 0
                clicks: 0
                sentToFriend: 0
                incorrectAddresses: 0
                technicalProblems: 0
                deliveryRate: 0
                clickRate: 0
                viewRate: 0
                status: scheduled
                mailFrom: info@example.org
                fromName: testing department
                links: [ ]
                recipientGroups:
                  - id: 159868
                    title: Test group
                viewOnlineURL: "https://app.cyberimpact.com/newsletter-view-online?ct=W8R14eU-Ptv4UeNdN1pKi4pofaHRVaoJwlhmFKiozSvZvfaY5DKjzkIX5H2ts4Yopq2tX4N6zrpLqlLmSk_Kfw~~"
        "400":
          description: Bad request
        "401":
          description: Unauthorized

  /mailings/{id}/recipients:
    get:
      tags:
        - Mailings
      summary: Retrieve recipients of the mailing
      description: Retrieve a paginated list of a mailing's recipients.
      operationId: getMailingRecipients
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
        - name: idGroup
          in: query
          description: Filter to only show recipients that were in the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
      responses:
        "200":
          description: Paginated list of mailing recipients
          content:
            application/json:
              schema:
                type: object
                properties:
                  recipients:
                    type: array
                    items:
                      $ref: "#/components/schemas/RecipientMember"
                  totalCount:
                    type: integer
                    example: 2
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: date_desc
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

  /mailings/{id}/recipients/delivered:
    get:
      tags:
        - Mailings
      summary: Retrieve recipients to which the mailing was successfully delivered
      description: Retrieve a paginated list of recipients to which the mailing was successfully delivered.
      operationId: getMailingRecipientsDelivered
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
        - name: idGroup
          in: query
          description: Filter to only show recipients that were in the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
      responses:
        "200":
          description: Paginated list of recipients the mailing was delivered to
          content:
            application/json:
              schema:
                type: object
                properties:
                  recipients:
                    type: array
                    items:
                      $ref: "#/components/schemas/RecipientMember"
                  totalCount:
                    type: integer
                    example: 2
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: date_desc
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

  /mailings/{id}/recipients/stopped:
    get:
      tags:
        - Mailings
      summary: Retrieve recipients for which the mailing was not sent because it was stopped
      description: |
        Retrieve a paginated list of recipients for which the mailing was not sent because it was stopped.
        If the mailing was not stopped, this will return an empty list.
      operationId: getMailingRecipientsStopped
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
        - name: idGroup
          in: query
          description: Filter to only show recipients that were in the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
      responses:
        "200":
          description: Paginated list of recipients for which sending was stopped
          content:
            application/json:
              schema:
                type: object
                properties:
                  recipients:
                    type: array
                    items:
                      $ref: "#/components/schemas/RecipientMember"
                  totalCount:
                    type: integer
                    example: 2
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: date_desc
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

  /mailings/{id}/recipients/hard-bounced:
    get:
      tags:
        - Mailings
      summary: Retrieve recipients which have hard bounced
      description: Retrieve a paginated list of a mailing's recipients which have hard bounced.
      operationId: getMailingRecipientsHardBounced
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
        - name: idGroup
          in: query
          description: Filter to only show recipients that were in the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
      responses:
        "200":
          description: Paginated list of hard-bounced recipients
          content:
            application/json:
              schema:
                type: object
                properties:
                  recipients:
                    type: array
                    items:
                      allOf:
                        - $ref: "#/components/schemas/RecipientMember"
                        - type: object
                          properties:
                            hardBouncedOn:
                              type: [ 'string', 'null' ]
                              example: "2020-10-02 15:32:26.111"
                  totalCount:
                    type: integer
                    example: 2
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: date_desc
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

  /mailings/{id}/recipients/soft-bounced:
    get:
      tags:
        - Mailings
      summary: Retrieve recipients which have soft bounced
      description: Retrieve a paginated list of a mailing's recipients which have soft bounced.
      operationId: getMailingRecipientsSoftBounced
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
        - name: idGroup
          in: query
          description: Filter to only show recipients that were in the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
      responses:
        "200":
          description: Paginated list of soft-bounced recipients
          content:
            application/json:
              schema:
                type: object
                properties:
                  recipients:
                    type: array
                    items:
                      allOf:
                        - $ref: "#/components/schemas/RecipientMember"
                        - type: object
                          properties:
                            softBouncedOn:
                              type: [ 'string', 'null' ]
                              example: "2020-10-02 15:32:26.111"
                  totalCount:
                    type: integer
                    example: 2
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: date_desc
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

  /mailings/{id}/recipients/unsubscribed:
    get:
      tags:
        - Mailings
      summary: Retrieve recipients which have unsubscribed from a mailing
      description: Retrieve a paginated list of a mailing's recipients which unsubscribed by using the unsubscribe link in the mailing.
      operationId: getMailingRecipientsUnsubscribed
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
        - name: idGroup
          in: query
          description: Filter to only show recipients that were in the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
      responses:
        "200":
          description: Paginated list of recipients who unsubscribed via the mailing
          content:
            application/json:
              schema:
                type: object
                properties:
                  recipients:
                    type: array
                    items:
                      allOf:
                        - $ref: "#/components/schemas/RecipientMember"
                        - type: object
                          properties:
                            unsubscribedOn:
                              type: [ 'string', 'null' ]
                              example: "2020-10-02 15:32:26.111"
                  totalCount:
                    type: integer
                    example: 2
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: date_desc
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

  /mailings/{id}/recipients/opened:
    get:
      tags:
        - Mailings
      summary: Retrieve recipients which have opened the mailing
      description: Retrieve a paginated list of a mailing's recipients which have opened the mailing.
      operationId: getMailingRecipientsOpened
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
        - name: idGroup
          in: query
          description: Filter to only show recipients that were in the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
      responses:
        "200":
          description: Paginated list of recipients who opened the mailing
          content:
            application/json:
              schema:
                type: object
                properties:
                  recipients:
                    type: array
                    items:
                      allOf:
                        - $ref: "#/components/schemas/RecipientMember"
                        - type: object
                          properties:
                            openedOn:
                              type: [ 'string', 'null' ]
                              example: "2020-10-02 15:32:26.111"
                  totalCount:
                    type: integer
                    example: 2
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: date_desc
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

  /mailings/{id}/recipients/clicked:
    get:
      tags:
        - Mailings
      summary: Retrieve recipients which have clicked in the mailing
      description: Retrieve a paginated list of a mailing's recipients which have clicked at least one link in the mailing.
      operationId: getMailingRecipientsClicked
      parameters:
        - name: id
          in: path
          required: true
          description: The mailing's numerical ID
          schema:
            type: integer
        - name: idGroup
          in: query
          description: Filter to only show recipients that were in the specified group ID
          schema:
            type: integer
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - email_asc
              - email_desc
              - language_asc
              - language_desc
              - fullname_asc
              - fullname_desc
              - date_asc
              - date_desc
              - updated_asc
              - updated_desc
      responses:
        "200":
          description: Paginated list of recipients who clicked a link in the mailing
          content:
            application/json:
              schema:
                type: object
                properties:
                  recipients:
                    type: array
                    items:
                      allOf:
                        - $ref: "#/components/schemas/RecipientMember"
                        - type: object
                          properties:
                            clickedOn:
                              type: [ 'string', 'null' ]
                              example: "2020-10-02 15:32:26.111"
                  totalCount:
                    type: integer
                    example: 2
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 20
                  sort:
                    type: string
                    example: date_desc
        "401":
          description: Unauthorized
        "404":
          description: Mailing not found

  /templates:
    get:
      tags:
        - Templates
      summary: Retrieve templates
      description: Retrieve a paginated list of the templates.
      operationId: getTemplates
      parameters:
        - name: page
          in: query
          description: The page of results to view
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: The number of results per page (max 10 000)
          schema:
            type: integer
            default: 20
        - name: sort
          in: query
          description: Sort order for results
          schema:
            type: string
            enum:
              - template_asc
              - template_desc
              - language_asc
              - language_desc
              - subject_asc
              - subject_desc
              - updated_asc
              - updated_desc
              - usage_asc
              - usage_desc
              - created_asc
              - created_desc
      responses:
        "200":
          description: Paginated list of templates
          content:
            application/json:
              schema:
                type: object
                properties:
                  templates:
                    type: array
                    items:
                      $ref: "#/components/schemas/Template"
                  totalCount:
                    type: integer
                    example: 150
                  page:
                    type: integer
                    example: 1
                  limit:
                    type: integer
                    example: 2
                  sort:
                    type: string
                    example: ""
        "401":
          description: Unauthorized

    post:
      tags:
        - Templates
      summary: Create template
      description: Create a new template.
      operationId: createTemplate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TemplateInput"
            example:
              title: This is a test template
              bodyHtml: "<b>Testing!</b>"
              bodyText: "Testing!"
      responses:
        "201":
          description: The template attributes
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplateDetail"
              example:
                id: 1541
                title: This is a test template
                bodyHtml: "<b>Testing!</b>"
                bodyText: "Testing!"
                createdOn: "2015-10-27 13:25:39.080"
                updatedOn: "2015-10-27 13:25:39.080"
        "400":
          description: Bad request
        "401":
          description: Unauthorized

  /templates/{id}:
    get:
      tags:
        - Templates
      summary: Retrieve a template
      description: Retrieve a specific template based on its ID.
      operationId: getTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: The template's numerical ID
          schema:
            type: integer
      responses:
        "200":
          description: The template attributes
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplateDetail"
              example:
                id: 1419
                title: ""
                bodyHtml: "<b>Testing !</b><p>this is just a test</p>"
                bodyText: "This is a test!"
                createdOn: "2014-11-10 15:38:38.827"
                updatedOn: "2014-11-10 15:38:38.827"
        "401":
          description: Unauthorized
        "404":
          description: Template not found

    put:
      tags:
        - Templates
      summary: Replace a template
      description: |
        Modify the representation of a template so that it becomes completely as specified.
        Unspecified attributes will be reset to their default empty values.
      operationId: replaceTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: The template's numerical ID
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TemplateInput"
            example:
              title: This is an updated template
              bodyHtml: "<b>Testing!</b>"
              bodyText: "Testing!"
      responses:
        "200":
          description: The template attributes
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplateDetail"
              example:
                id: 1541
                title: This is an updated template
                bodyHtml: "<b>Testing!</b>"
                bodyText: "Testing!"
                createdOn: "2015-10-27 13:25:39.080"
                updatedOn: "2015-10-27 13:43:14.310"
        "400":
          description: Bad request
        "401":
          description: Unauthorized
        "404":
          description: Template not found

    delete:
      tags:
        - Templates
      summary: Delete a template
      description: Delete a specific template based on its ID.
      operationId: deleteTemplate
      parameters:
        - name: id
          in: path
          required: true
          description: The template's numerical ID
          schema:
            type: integer
      responses:
        "200":
          description: The ID of the template and its deletion status
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
              example:
                "1541": deleted
        "401":
          description: Unauthorized
        "404":
          description: Template not found

  /batches/{id}:
    get:
      tags:
        - Batches
      summary: Retrieve a batch
      description: |
        Retrieve a specific batch based on its ID. This is useful to check whether a batch has finished
        processing and to get the results. Some requests in the batch may have succeeded while others failed.
        The `result` field provides the details.
      operationId: getBatch
      parameters:
        - name: id
          in: path
          required: true
          description: The batch's numerical ID
          schema:
            type: integer
        - name: showErrorDetails
          in: query
          description: Return the details of invalid rows
          schema:
            type: boolean
      responses:
        "200":
          description: The batch details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Batch"
              example:
                id: 176
                batchType: unsubscribe
                batchJson:
                  batchType: unsubscribe
                  ids: [ 1, 2, 3, 4, 5, "6", "7", "test@example.org", "foo@bar.com", "random@company.ca" ]
                createdOn: "2015-10-28 11:55:56.217"
                status: COMPLETED
                result:
                  errors:
                    - id: "7"
                      description: "Members with ids 7 do not exists"
                    - id: "6"
                      description: "Members with ids 6 do not exists"
                    - id: 5
                      description: "Members with ids 5 do not exists"
                    - id: 4
                      description: "Members with ids 4 do not exists"
                    - id: 3
                      description: "Members with ids 3 do not exists"
                    - id: 2
                      description: "Members with ids 2 do not exists"
                    - id: 1
                      description: "Members with ids 1 do not exists"
                  successes:
                    - "random@company.ca"
                    - "foo@bar.com"
                    - "test@example.org"
        "401":
          description: Unauthorized
        "404":
          description: Batch not found

  /batches:
    post:
      tags:
        - Batches
      summary: Add a batch
      description: |
        Submit a batch for processing. Batches can be of three types: **addMembers**, **unsubscribe**, and **deleteMembers**.

        ### Batch type: unsubscribe
        Provide a list of member IDs (integer) or email addresses (string) to unsubscribe.

        ### Batch type: deleteMembers
        Provide a list of member IDs (integer) or email addresses (string) to delete.

        ### Batch type: addMembers
        Add or update members in bulk. Key behaviors:
        - If a member already exists, it is updated with the provided information.
        - If a field is empty and data already exists for that field, the existing data is kept.
        - To explicitly clear a field, use the special string `__EMPTY__`.
        - All submitted members will be added to the specified groups (in addition to any existing group memberships).
        - The `relationType` field is required and accepts: `express-consent`, `active-clients`, `information-request`,
          `business-card`, `web-contacts`, `purchased-list`, `contest-participants`, `mixed-list`, `inactive-clients`,
          `association-members`, `employees`, `partners`.
      operationId: createBatch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - title: Unsubscribe batch
                  type: object
                  required:
                    - batchType
                    - ids
                  properties:
                    batchType:
                      type: string
                      enum:
                        - unsubscribe
                      example: unsubscribe
                    ids:
                      type: array
                      items:
                        oneOf:
                          - type: string
                          - type: integer
                      example: [ 1, 2, 3, "test@example.org", "foo@bar.com" ]
                - title: Delete members batch
                  type: object
                  required:
                    - batchType
                    - ids
                  properties:
                    batchType:
                      type: string
                      enum:
                        - deleteMembers
                      example: deleteMembers
                    ids:
                      type: array
                      items:
                        oneOf:
                          - type: string
                          - type: integer
                      example: [ 1, 2, 3, "test@example.org", "foo@bar.com" ]
                - title: Add members batch
                  type: object
                  required:
                    - batchType
                    - relationType
                    - members
                  properties:
                    batchType:
                      type: string
                      enum:
                        - addMembers
                      example: addMembers
                    relationType:
                      type: string
                      enum:
                        - express-consent
                        - active-clients
                        - information-request
                        - business-card
                        - web-contacts
                        - purchased-list
                        - contest-participants
                        - mixed-list
                        - inactive-clients
                        - association-members
                        - employees
                        - partners
                      example: mixed-list
                    defaultConsentDate:
                      type: string
                      format: date
                      example: "2014-06-15"
                    defaultConsentProof:
                      type: string
                      maxLength: 255
                      example: Bought on our website
                    groups:
                      type: array
                      items:
                        type: integer
                      example: [ 1, 2, 3, 4, 5 ]
                    members:
                      type: array
                      items:
                        type: object
                        required:
                          - email
                        properties:
                          email:
                            type: string
                            format: email
                          firstname:
                            type: string
                          lastname:
                            type: string
                          company:
                            type: string
                          gender:
                            type: string
                          language:
                            type: string
                          postalCode:
                            type: string
                          country:
                            type: string
                          note:
                            type: string
                          birthdate:
                            type: string
                          customFields:
                            type: object
                            additionalProperties: true
                          consentDate:
                            type: string
                          consentProof:
                            type: string
            examples:
              unsubscribe:
                summary: Unsubscribe members in batch
                value:
                  batchType: unsubscribe
                  ids: [ 1, 2, 3, 4, 5, "6", "7", "test@example.org", "foo@bar.com", "random@company.com" ]
              deleteMembers:
                summary: Delete members in batch
                value:
                  batchType: deleteMembers
                  ids: [ 1, 2, 3, 4, 5, "6", "7", "test@example.org", "foo@bar.com", "random@company.com" ]
              addMembers:
                summary: Add members in batch
                value:
                  batchType: addMembers
                  relationType: mixed-list
                  defaultConsentDate: "2014-06-15"
                  defaultConsentProof: Bought on our website
                  groups: [ 1, 2, 3, 4, 5 ]
                  members:
                    - firstname: John
                      lastname: Doe
                      company: John Doe Company
                      email: john.doe@example.org
                      gender: m
                      language: fr_ca
                      postalCode: "A0A 0A0"
                      country: CA
                      note: "He's awesome"
                      birthdate: "1980-01-01"
                      customFields:
                        "1": "this is a test!"
                        "2": 200
                        "3": 1.5
                        "4": "2000-01-01"
                      consentDate: "2014-01-18"
                      consentProof: "Invoice #12345"
                    - firstname: Jane
                      lastname: Doe
                      company: Jane Doe Company inc
                      email: jane.doe@example.org
                      gender: f
                      language: en_ca
                      postalCode: "90210"
                      country: US
                      note: "She's awesome"
                      birthdate: "1982-02-01"
                      customFields:
                        "1": "this is a test!"
                        "2": 200
                        "3": 1.5
                        "4": "2000-01-01"
                      consentDate: "2015-12-06"
                      consentProof: "Invoice #54321"
                    - firstname: Joe
                      lastname: Bleau
                      email: joe.bleau@example.org
      responses:
        "201":
          description: The newly created batch (status will be NEW until processed)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Batch"
              examples:
                unsubscribe:
                  summary: Unsubscribe batch created
                  value:
                    id: 176
                    batchType: unsubscribe
                    batchJson:
                      batchType: unsubscribe
                      ids: [ 1, 2, 3, 4, 5, "6", "7", "test@example.org", "foo@bar.com", "random@company.ca" ]
                    createdOn: "2015-10-28 11:55:56.217"
                    status: NEW
                    result: null
                deleteMembers:
                  summary: Delete members batch created
                  value:
                    id: 176
                    batchType: deleteMembers
                    batchJson:
                      batchType: deleteMembers
                      ids: [ 1, 2, 3, 4, 5, "6", "7", "test@example.org", "foo@bar.com", "random@company.ca" ]
                    createdOn: "2015-10-28 11:55:56.217"
                    status: NEW
                    result: null
                addMembers:
                  summary: Add members batch created
                  value:
                    id: 210
                    batchType: addMembers
                    batchJson:
                      batchType: addMembers
                      relationType: mixed-list
                      defaultConsentDate: "2014-06-15"
                      defaultConsentProof: Bought on our website
                      groups: [ 1, 2, 3, 4, 5 ]
                      members:
                        - firstname: John
                          lastname: Doe
                          company: John Doe Company inc
                          email: john.doe@example.org
                          gender: m
                          language: fr_ca
                          postalCode: "A0A 0A0"
                          country: CA
                          note: "He's awesome"
                          birthdate: "1980-01-01"
                          customFields:
                            "1": "this is a test!"
                            "2": 200
                            "3": 1.5
                            "4": "2000-01-01"
                          consentDate: "2014-01-18"
                          consentProof: "Invoice #12345"
                        - firstname: Jane
                          lastname: Doe
                          company: Jane Doe Company Inc
                          email: jane.doe@example.org
                          gender: f
                          language: en_ca
                          postalCode: "90210"
                          country: US
                          note: "She's awesome"
                          birthdate: "1982-02-01"
                          customFields:
                            "1": "this is a test!"
                            "2": 200
                            "3": 1.5
                            "4": "2000-01-01"
                          consentDate: "2015-12-06"
                          consentProof: "Invoice #54321"
                        - firstname: Joe
                          lastname: Bleau
                          email: joe.bleau@example.org
                    createdOn: "2015-11-06 15:06:52.657"
                    status: NEW
                    result: null
        "400":
          description: Bad request — invalid batch JSON
        "401":
          description: Unauthorized

  /tokens:
    post:
      tags:
        - Tokens
      summary: Generate an API token
      description: Generate a token that will be associated to your account and be used to call this API.
      operationId: generateToken
      responses:
        "200":
          description: The newly generated API token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Token"
              example:
                tokenUniqueId: thisIsTheUniqueKeyOfTheToken
                token: ThisIsTheTokenContent
                expiration: "2032-01-01 12:34:56"
        "401":
          description: Unauthorized

  /tokens/{tokenUniqueId}:
    delete:
      tags:
        - Tokens
      summary: Revoke an API token
      description: |
        Permanently revoke the API token identified by `tokenUniqueId`.
        Once revoked, the token can no longer be used to authenticate API requests.
      operationId: revokeToken
      parameters:
        - name: tokenUniqueId
          in: path
          required: true
          description: The unique identifier of the token to revoke
          schema:
            type: string
      responses:
        "200":
          description: The token unique ID and its deletion status
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
              example:
                thisIsTheTokenUniqueId: deleted
        "401":
          description: Unauthorized
        "404":
          description: Token not found
