openapi: 3.0.3
info:
  title: Sertifier Credential API Documentation
  version: '3.3'
  description: |
    Sertifier is made out of four main components; which are the _Design_, the _Detail_, the _EmailTemplate_ and the _Campaign_.

    The general workflow in Sertifier is the following:

    1. The Design is created for the credential. The credential is either a certificate or a badge
    2. The Detail is created for the credential that is going to be issued. The Detail contains the data about the credential.
    3. The EmailTemplate is created. This will be the email that is sent to the credential recipients.
    4. A new Campaign is created and the Design, Detail and EmailTemplate are placed in the Campaign.
    5. The Recipients are added to the Campaign.
    6. The Credentials are published to the Recipients.

    Each component and usage will be explained thoroughly in the following documentation.

    Please keep in mind, for every date operation, **Server's local time is UTC**.

    ## API Version

    The version of the API that is used is handled with a specified key set to the _headers_. The current version is **3.3** and the header key is **"api-version"**. This value has to be set in every request in order to use the current version of the service.

    ```
    {
        "Content-Type": "application/json",
        "api-version": "3.3",
        "secretKey": "..."
    }
    ```

    ## Authentication

    Authentication in Sertifier is done via the Private API Key which belongs to your organization. To find your API key, go to **Settings > API & Integrations** in the Sertifier app.

    In **every** request that is sent to b2b.sertifier.com, the API Key **must** be in the header. A request without the key will result in a 403 status response.

    The API Key has to be set in the header corresponding to the key **"secretKey"**.

    ```
    {
        "Content-Type": "application/json",
        "api-version": "3.3",
        "secretKey": "..."
    }
    ```

    ## Webhooks

    Sertifier provides webhooks for tracking all credential events. Webhooks allow your application to receive real-time notifications about changes and updates to credentials, ensuring you stay informed about every important event.

    For further details and setup instructions, please contact us at [support@sertifier.com](mailto:support@sertifier.com).

    ## Contact Us

    You can always contact us at support@sertifier.com for any questions or issues.

    [https://sertifier.com](https://sertifier.com)

servers:
  - url: https://b2b.sertifier.com/

security:
  - secretKey: []

tags:
  - name: Authentication
    description: Test your API authentication.
  - name: Design
    description: |
      The Design has to be created in the web application directly at https://app.sertifier.com, but operations such as the following can be done via the API:

      - Searching the designs that belong to your organization
      - Getting detailed information about a Design
      - Copying a Design
      - Deleting a design
  - name: Detail
    description: |
      Details hold the main data about the credentials. The data in Detail will be what users see when the certificate is issued. They are reusable for different Campaigns, but they cannot be changed after the `status` changes to _Sent_.

      The `status` field of the Detail is important because it controls whether the entity can be edited or used in a Campaign. If a detail has valid `type`, `duration`, `title`, `description`, `earningCriteria` and at least one skill then it will be marked as _Ready_.

      #### Enums

      **Status:**
      - 0 - NotFinished
      - 1 - Ready
      - 2 - Sent

      **Type:**
      - 0 - Field Event
      - 1 - Online Event
      - 2 - Class Course
      - 3 - Online Course
      - 4 - Webinar
      - 5 - Achievement
      - 6 - License
      - 7 - Appreciation
      - 8 - Promotional Course
      - 9 - Membership
      - 10 - Graduation
      - 11 - Hybrid Event
      - 12 - Hybrid Course

      **Duration Type:**
      - 1 - Hour
      - 2 - Day
      - 3 - Week
      - 4 - Month
      - 5 - Year
      - 6 - Minute

      **Cost:**
      - 0 - Free
      - 1 - Paid
      - 2 - NA

      **Level:**
      - 0 - Beginner
      - 1 - Intermediate
      - 2 - Advanced
      - 3 - Experienced
      - 4 - Professional
      - 5 - NA
  - name: EmailTemplate
    description: |
      EmailTemplate is the email that is sent to the credential recipients. Once created, they can be used in multiple Campaigns.

      They can only be created and edited via the web application directly at https://app.sertifier.com.

      The following operations can be done via the API:

      - Get details of the EmailTemplate
      - Search your organizations EmailTemplates
      - Delete EmailTemplate
      - Copy EmailTemplate
  - name: Campaign
    description: |
      Campaigns are the components where the Design, Detail, EmailTemplate and Recipient come together. The credentials will be sent by creating and sending the Campaign.

      Credentials can be created from the Campaign in two different ways:

      - Adding all of the Recipients to the Campaign and then publishing them all together
      - Sending the credential to the Recipient as soon as its added to the Campaign

      A Campaign can only issue credentials when it is associated with a Design, Detail and EmailTemplate.
      Details with the `status` of _NotFinished_ cannot be linked to the Campaign.
      Once a credential is created from the Campaign, the `status` will change to _Sent_.

      Recipients will not see the `title` of the Campaign, it is just for you.

      `mailSubject` will be the subject and `fromName` will be the sender name of the emails which the recipients will receive. Default values will be used if left blank.

      The `fromAddress` can only be used if **branding** is enabled in your organization and if you have made the necessary SMTP domain configurations from the web app. For more information about branding features, please visit https://sertifier.com/en/pricing.

      `privateCampaign` is used to issue private credentials. These credentials will not be shown in search results. They will only be accessible by the verification link the recipient receives via email.

      #### Enums

      **Status:**
      - 0 - NoEntry
      - 1 - Draft
      - 2 - Scheduled
      - 3 - Sent
  - name: Recipient
    description: |
      Recipients are the unique set of emails that credentials have been issued to.

      The following operations can be done via the API:

      - Add a Recipient
      - Update a Recipient
      - Delete a Recipient
      - Search Recipients
  - name: Credential
    description: |
      All Credentials belong to a specific Campaign. Adding a Credential to a Campaign is only done from the `campaign/addCredentials` address.

      The following operations can be done via the API:

      - Get a Credential
      - Update a Credential
      - Delete a Credential
      - Search Credentials
      - Publish the Credential
      - Generate the PDF link of the Credential for download
  - name: Attribute
    description: |
      Attributes are the parameters that are first created then added to the designs.
      There are default attributes which come with every design, but can be removed if wanted, and there are custom attributes which can be created via the API.

      After they are created they can be added to the design but this can only be done through the app at https://app.sertifier.com.
      When an attribute is added to the design, the recipients must have a value for the added attribute.

      The following operations can be done with the API:

      - Add Attributes
      - Update Attributes
      - Delete Attributes
      - Search Attributes
  - name: Webhooks
    description: |
      Sertifier provides webhooks for tracking all credential events. Webhooks allow your application to receive real-time notifications about changes and updates to credentials, ensuring you stay informed about every important event.

      For further details and setup instructions, please contact us at [support@sertifier.com](mailto:support@sertifier.com).
  - name: Contact Us
    description: |
      You can always contact us at support@sertifier.com for any questions or issues.

      [https://sertifier.com](https://sertifier.com)

paths:
  /Test:
    get:
      tags:
        - Authentication
      summary: Test Authentication
      description: Endpoint for testing your authentication.
      operationId: testAuthentication
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      responses:
        '200':
          description: Successful authentication
          content:
            application/json:
              schema:
                type: string
              example: "Welcome to Sertifier!"

  /design/{design_id}:
    get:
      tags:
        - Design
      summary: Get Design
      description: |
        Returns detailed information about the Design. The `id` of the Design is placed in the parameters.

        The `preview` field in the response will contain the HTML of the design.
      operationId: getDesign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: design_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Design
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  title: "string"
                  type: 1
                  createDate: "2023-01-23T09:48:28.745797"
                  preview: "string"
                content: null
    delete:
      tags:
        - Design
      summary: Delete Design
      description: |
        Delete a design. The `id` of the Design which is going to be deleted is placed in the parameters.
        Designs that belong to a _Campaign_ that has been sent cannot be deleted.
      operationId: deleteDesign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: design_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Design
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Record has been successfully deleted."
                hasError: false
                validationErrors: []
                data: true
                content: null

  /design/search:
    post:
      tags:
        - Design
      summary: Search Designs
      description: |
        Returns the organizations Designs in paginated format. The pagination is handled with the `startIndex` and `length` keys in the request body.
        There are two filtering options within the body:

        - `type` field is used for filtering between certificate and badge designs
          - 1 -> certificate
          - 2 -> badge
        - `searchTerm` field is searched within the titles of the designs

        The `preview` field in the response will contain the HTML of the design.
      operationId: searchDesigns
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DesignSearchRequest'
            example:
              startIndex: 0
              length: 10
              type: 1
              searchTerm: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  results:
                    - id: "string"
                      title: "string"
                      type: 1
                      createDate: "2023-02-08T12:16:19.356893"
                      preview: "string"
                  total: 6
                content: null

  /design/copy:
    post:
      tags:
        - Design
      summary: Copy Design
      description: |
        This endpoint creates a copy of the original Design. This can be used when organizations want to make a small change on the Design for new credentials, but don't want to change the old ones.

        The request body contains the `id` of the original Design.
      operationId: copyDesign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CopyRequest'
            example:
              id: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Record has been successfully created"
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  title: "string"
                  type: 2
                  createDate: "2023-02-13T22:40:46.6292358Z"
                  preview: "string"
                content: null

  /detail:
    post:
      tags:
        - Detail
      summary: Add Detail
      description: |
        Creates a detail.

        Details for the body of the request:

        - `type` enum value, the type of event which the credential is being issued for
        - `title` the credential title
        - `description` the credential description
        - _Duration_ the duration of the event
          - The duration is a combination of two fields `durationNumber` and `durationType`
          - `durationNumber` indicates the integer value for the `durationType` enum value which is the unit time
        - `cost` enum value, the cost of the event or course
        - _Expire Date_ expire date of the credential, **not required**
          - There are **two different options for the expire date of the credential**
            1. Set an exact expire date for every credential sent with this _Detail_ (ex: 01/01/2023). This option uses `expireDate` (DateTime) field
            2. Set a time span which will be added to the credential's issue date (ex: 2 years). This option uses `expireDateNumber` (int) and `expireDateType` (DurationType enum) fields
          - If none of these options are used, the expire date will be set to _null_
          - **If the expire date is set**, you have the option of customizing your expiry date reminder email schedule. With the `expiryReminderDays` field, you can send *how many days before the expire date* you want reminders to be sent by email to the recipient.
            - You can set a *maximum of 3* reminder emails
            - The field is a list of `int`, where each integer corresponds to the count of days before the expire date. So for example `[1, 2, 4]` means that an email will be sent 1 day, 2 days and 4 days before the credential expires.
        - `level` enum value, level of the event or course
        - `earningCriteria` the information given as earning criteria for the course or event, **not required**
          - The input can be given as HTML code, the HTML will be rendered in the credential verification page below the "Earning Criteria" title
        - `skills` the skills related to the Detail, minimum one skill is required for the `status` to be _Ready_
          - The skills can be obtained from the `/SearchSkills` address
            - The `skillId` field can be retrieved from the `/SearchSkills` address, this field can be left blank to add custom skills to the Detail
          - `languageCode` has to be _en_ or _tr_
        - `dontSendExpireDateEmail` field is a boolean field used for controlling if users should be notified automatically when the expire date of credential is approaching
      operationId: addDetail
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DetailRequest'
            example:
              type: 0
              title: "string"
              description: "string"
              durationNumber: 10
              durationType: 1
              cost: 1
              expireDate: "2023-01-01"
              level: 1
              earningCriteria: "string"
              dontSendExpireDateEmail: true
              skills:
                - skillId: "string"
                  title: "string"
                  languageCode: "en"
              expiryReminderDays: [1, 4]
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Detail added successfully."
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  type: 0
                  title: "string"
                  description: "string"
                  duration: 5
                  durationNumber: 10
                  durationType: 1
                  cost: 1
                  expireDate: "2023-01-01T00:00:00"
                  expireDateNumber: null
                  expireDateType: null
                  level: 1
                  status: 1
                  organizationId: "string"
                  skills:
                    - title: "string"
                      skillId: "string"
                      languageCode: "en"
                  attendeeCount: 0
                  courseRating: 0.0
                  courseRatingCount: 0
                  earningCriteria: "string"
                  dontSendExpireDateEmail: false
                  expiryReminderDays: [1, 4]
                content: null

  /detail/{detail_id}:
    put:
      tags:
        - Detail
      summary: Update Detail
      description: |
        Update a Detail with the `id`, placed in the parameters. Only the provided fields in the request body will be updated, the rest will remain unchanged. If skills are provided, old skills will be deleted and new skills will be created in place.

        If Detail `status` is _Sent_, it can **not** be updated. You can copy the Detail with the `/Copy` address if you wish to use an edited version of the original Detail.

        Details for the body of the request:

        - `type` enum value, the type of event which the credential is being issued for
        - `title` the credential title
        - `description` the credential description
        - _Duration_ the duration of the event
          - The duration is a combination of two fields `durationNumber` and `durationType`
          - `durationNumber` indicates the integer value for the `durationType` enum value which is the unit time
        - `cost` enum value, the cost of the event or course
        - _Expire Date_ expire date of the credential, **not required**
          - There are **two different options for the expire date of the credential**
            1. Set an exact expire date for every credential sent with this _Detail_ (ex: 01/01/2023). This option uses `expireDate` (DateTime) field
            2. Set a time span which will be added to the credential's issue date (ex: 2 years). This option uses `expireDateNumber` (int) and `expireDateType` (DurationType enum) fields
          - If none of these options are used, the expire date will be set to _null_
        - `level` enum value, level of the event or course
        - `earningCriteria` the information given as earning criteria for the course or event, **not required**
          - The input can be given as HTML code, the HTML will be rendered in the credential verification page below the "Earning Criteria" title
        - `skills` the skills related to the Detail, minimum one skill is required for the `status` to be _Ready_
          - The skills can be obtained from the `/SearchSkills` address
            - The `skillId` field can be retrieved from the `/SearchSkills` address, this field can be left blank to add custom skills to the Detail
          - `languageCode` has to be _en_ or _tr_
        - `dontSendExpireDateEmail` field is a boolean field used for controlling if users should be notified automatically when the expire date of credential is approaching
      operationId: updateDetail
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: detail_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Detail
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DetailRequest'
            example:
              type: 0
              title: "string"
              description: "string"
              durationNumber: 10
              durationType: 1
              cost: 1
              expireDate: "2023-01-01"
              level: 1
              earningCriteria: "string"
              dontSendExpireDateEmail: true
              skills:
                - skillId: "string"
                  title: "string"
                  languageCode: "en"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Detail updated successfully."
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  type: 0
                  title: "string"
                  description: "string"
                  duration: 5
                  durationNumber: 10
                  durationType: 1
                  cost: 1
                  expireDate: "2023-01-01T00:00:00"
                  expireDateNumber: null
                  expireDateType: null
                  level: 1
                  status: 1
                  organizationId: "string"
                  skills:
                    - title: "string"
                      skillId: "string"
                      languageCode: "en"
                  attendeeCount: 0
                  courseRating: 0.0
                  courseRatingCount: 0
                  earningCriteria: "string"
                  dontSendExpireDateEmail: true
                content: null
    get:
      tags:
        - Detail
      summary: Get Detail
      description: Gives the single Detail with the given `id` which is placed in the parameters.
      operationId: getDetail
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: detail_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Detail
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  type: 0
                  title: "string"
                  description: "string"
                  duration: 5
                  durationNumber: 10
                  durationType: 1
                  cost: 1
                  expireDate: "2023-01-01T00:00:00"
                  expireDateNumber: null
                  expireDateType: null
                  level: 1
                  status: 1
                  organizationId: "string"
                  skills:
                    - title: "string"
                      skillId: "string"
                      languageCode: "en"
                  attendeeCount: 0
                  courseRating: 0.0
                  courseRatingCount: 0
                  earningCriteria: "string"
                  dontSendExpireDateEmail: true
                content: null

  /detail/search:
    post:
      tags:
        - Detail
      summary: Search Details
      description: |
        Returns the organizations Details in paginated format. The pagination is handled with the `startIndex` and `length` keys in the request body.
        There is one filtering option within the body:

        - `searchTerm` field is searched within the titles of the Details
      operationId: searchDetails
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
            example:
              startIndex: 0
              length: 10
              searchTerm: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  results:
                    - id: "string"
                      type: 0
                      title: "string"
                      description: "string"
                      duration: 5
                      durationNumber: 10
                      durationType: 1
                      cost: 1
                      expireDate: "2023-01-01T00:00:00"
                      expireDateNumber: null
                      expireDateType: null
                      level: 1
                      status: 1
                      organizationId: "string"
                      skills:
                        - title: "string"
                          skillId: "string"
                          languageCode: "en"
                      attendeeCount: 0
                      courseRating: 0.0
                      courseRatingCount: 0
                      earningCriteria: "string"
                      dontSendExpireDateEmail: true
                  total: 30
                content: null

  /detail/searchSkills:
    post:
      tags:
        - Detail
      summary: Search Skills
      description: |
        This endpoint returns lists of the skills in the Sertifier library which matches your search. The `skillId` in the response should be used while adding skills to the Detail.
      operationId: searchSkills
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SkillSearchRequest'
            example:
              startIndex: 0
              length: 10
              searchTerm: "string"
              language: "en"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "string"
                hasError: false
                validationErrors: []
                data:
                  - title: "string"
                    skillId: "string"
                    languageCode: "en"
                content: null

  /emailTemplate/{emailtemplate_id}:
    get:
      tags:
        - EmailTemplate
      summary: Get EmailTemplate
      description: Returns all of the details of the _EmailTemplate_. Takes the `id` of the _EmailTemplate_ in the parameters.
      operationId: getEmailTemplate
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: emailtemplate_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the EmailTemplate
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  createDate: "2023-02-08T12:47:40.572573"
                  title: "string"
                content: null
    delete:
      tags:
        - EmailTemplate
      summary: Delete EmailTemplate
      description: |
        Deletes the _EmailTemplate_ with the given `id` which is placed in the parameters.
        EmailTemplate cannot be deleted if it belongs to a _Sent_ Campaign. You have to delete the Campaign first.
      operationId: deleteEmailTemplate
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: emailtemplate_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the EmailTemplate
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Email template with id: 08db0e17-2a2c-4abf-0282-05c38c886347 is deleted successfully."
                hasError: false
                validationErrors: []
                data: true
                content: null

  /emailTemplate/search:
    post:
      tags:
        - EmailTemplate
      summary: Search EmailTemplates
      description: |
        Returns the organizations EmailTemplates in paginated format. The pagination is handled with the `startIndex` and `length` keys in the request body.
        There is one filtering option within the body:

        - `searchTerm` field is searched within the titles of the EmailTemplates
      operationId: searchEmailTemplates
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
            example:
              startIndex: 0
              length: 10
              searchTerm: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  results:
                    - id: "string"
                      createDate: "2023-02-08T12:47:40.572573"
                      title: "string"
                  total: 10
                content: null

  /emailTemplate/copy:
    post:
      tags:
        - EmailTemplate
      summary: Copy EmailTemplate
      description: |
        This endpoint creates a copy of the original EmailTemplate.

        The request body contains the `id` of the original EmailTemplate.
      operationId: copyEmailTemplate
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CopyRequest'
            example:
              id: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Record has been successfully created"
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  createDate: "2023-02-13T23:08:05.7666462Z"
                  title: "string"
                content: null

  /campaign:
    post:
      tags:
        - Campaign
      summary: Add Campaign
      description: |
        Creates a Campaign.

        Details for the body of the request:

        - `title` Campaign title
        - `mailBody` Campaign mail body
        - `fromName` Campaign mail sender name
        - `fromAddress` Campaign mail sender email address
        - `emailTemplateId` the Id of the EmailTemplate which is going to be linked to the Campaign
        - `designId` the Id of the certificate Design which is going to be linked to the Campaign
        - `badgeId` the Id of the badge Design which is going to be linked to the Campaign
        - `detailId` the Id of the Detail which is going to be linked to the Campaign
        - `privateCampaign` boolean field used for controlling whether the credentials in the Campaign are shown in search results
      operationId: addCampaign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignRequest'
            example:
              title: "string"
              detailId: "string"
              badgeId: "string"
              designId: "string"
              emailTemplateId: "string"
              emailFromName: "string"
              emailSubject: "string"
              emailfromAddress: "string"
              privateCampaign: false
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Campaign created with the id in the response data."
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  createDate: "2023-02-14T08:26:09.5597256Z"
                  updateDate: "2023-02-14T08:26:09.5597259Z"
                  title: "string"
                  detailId: "string"
                  designId: "string"
                  badgeId: "string"
                  emailTemplateId: "string"
                  emailFromName: "string"
                  emailSubject: "string"
                  emailFromAddress: "string"
                  privateCampaign: false
                  status: 1
                content: null

  /campaign/{campaign_id}:
    get:
      tags:
        - Campaign
      summary: Get Campaign
      description: Returns the _Campaign_ with the given `id`. The `id` value is given in the parameters.
      operationId: getCampaign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: campaign_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Campaign
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  createDate: "2023-01-26T23:24:49.617882"
                  updateDate: "2023-02-03T13:58:43.9067"
                  title: "string"
                  detailId: "string"
                  designId: "string"
                  badgeId: "string"
                  emailTemplateId: "string"
                  emailFromName: "string"
                  emailSubject: "string"
                  emailFromAddress: null
                  privateCampaign: false
                  status: 3
                content: null
    put:
      tags:
        - Campaign
      summary: Update Campaign
      description: |
        Updates the Campaign with the given `id`. The provided fields will be updated, the rest will remain unchanged except for `designId` and `badgeId`. Those fields can be set to `null`.

        Details for the body of the request:

        - `title` Campaign title
        - `mailBody` Campaign mail body
        - `fromName` Campaign mail sender name
        - `fromAddress` Campaign mail sender email address
        - `emailTemplateId` the Id of the EmailTemplate which is going to be linked to the Campaign
        - `designId` the Id of the certificate Design which is going to be linked to the Campaign
        - `badgeId` the Id of the badge Design which is going to be linked to the Campaign
        - `detailId` the Id of the Detail which is going to be linked to the Campaign
      operationId: updateCampaign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: campaign_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Campaign
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignRequest'
            example:
              title: "string"
              detailId: "string"
              badgeId: "string"
              designId: "string"
              emailTemplateId: "string"
              emailFromName: "string"
              emailSubject: "string"
              emailfromAddress: "string"
              privateCampaign: false
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Campaign updated successfully."
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  createDate: "string"
                  updateDate: "string"
                  title: "string"
                  detailId: "string"
                  designId: "string"
                  badgeId: "string"
                  emailTemplateId: "string"
                  emailFromName: "string"
                  emailSubject: "string"
                  emailFromAddress: "string"
                  privateCampaign: false
                content: null
    delete:
      tags:
        - Campaign
      summary: Delete Campaign
      description: |
        Deletes the Campaign with the given `id`. If the Campaign has _status_ **sent**, the credentials created from the Campaign will also be deleted. The `id` is passed in the parameters.
      operationId: deleteCampaign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: campaign_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Campaign
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Campaign deleted successfully."
                hasError: false
                validationErrors: []
                data: null
                content: null

  /campaign/search:
    post:
      tags:
        - Campaign
      summary: Search Campaigns
      description: |
        Returns the organizations Campaigns in paginated format. The pagination is handled with the `startIndex` and `length` keys in the request body.
        There are two filtering options within the body:

        - `searchTerm` field is searched within the titles of the Campaigns
        - `status` field takes in the `status` enum values in an array to filter the results
      operationId: searchCampaigns
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignSearchRequest'
            example:
              startIndex: 0
              length: 10
              status: [1, 2, 3]
              searchTerm: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  results:
                    - id: "string"
                      createDate: "2022-09-27T22:08:45.295692"
                      updateDate: "2023-02-14T08:23:48.938713"
                      title: "string"
                      detailId: "string"
                      designId: "string"
                      badgeId: "string"
                      emailTemplateId: "string"
                      emailFromName: "string"
                      emailSubject: "string"
                      emailFromAddress: "string"
                      privateCampaign: false
                      status: 1
                  total: 10
                content: null

  /campaign/addCredentials:
    post:
      tags:
        - Campaign
      summary: Add Credentials to Campaign
      description: |
        Add the Credentials to the Campaigns. The request body allows you to add multiple Credentials to multiple Campaigns.

        A Credential can be added without an email, but in this case when the credential is published, the recipient will not be notified via email.

        If `quickPublish` is _true_ for a Credential, it will be directly published and sent to the Recipient. This field is widely used for not having to send a second request to publish the created Credentials. The Credential will be placed in a queue when published and the `certificateImageLink`, `badgeImageLink` and `verificationLink` fields in the response will start working once the Credential is out of the queue. They are returned in the response directly so that you can save them if needed.

        `externalId` is used for linking the credential with a specific entity that is in your database. It is used when you want to receive all of the credentials which are linked to a specific entity. Any kind of identifier can be used, an example would be the id of an user in your database.

        `attributes` are used when the Design or EmailTemplate has **custom** Attributes attached to them. The `id` of the Attributes can be received from the Attribute controller. Leave the list empty if no **custom** Attributes are used.

        Details for the body of the request:

        - `credentials` credentials list
          - `campaignId` id of the Campaign the Credential will be created in
          - `name` Recipient name
          - `email` Recipient email
          - `issueDate` issue date of credential, will be set to the time of request if omitted
          - `quickPublish` used for publishing the credential as soon as its created
          - `externalId` external id of the Credential
          - `attributes` list of attributes and the corresponding values for the Credential
            - `id` Attribute id
            - `value` Attribute value
          - `dontSendEmail` controls if an email notification should be sent to the recipient. No email will be sent if set to `true`, default is `false`

        The response will be a dictionary which will have the different `campaignId` values sent in the request as keys, and the Credential list which was added to that Campaign as the value.
      operationId: addCredentialsToCampaign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddCredentialsRequest'
            example:
              credentials:
                - campaignId: "string"
                  name: "string"
                  email: "string"
                  issueDate: "2023-01-01"
                  expireDate: "2023-01-01"
                  quickPublish: true
                  externalId: "string"
                  attributes:
                    - id: "string"
                      value: "string"
                  dontSendEmail: false
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Credentials added successfully to campaigns."
                hasError: false
                validationErrors: []
                data:
                  CAMPAIGN_ID:
                    - id: "string"
                      name: "string"
                      email: "string"
                      status: 1
                      certificateNo: "string"
                      issueDate: "2023-01-01T00:00:00"
                      externalId: "string"
                      attributes:
                        - id: "string"
                          value: "string"
                      certificateImageLink: "string"
                      badgeImageLink: "string"
                      verificationLink: "string"
                      expireDate: "2023-01-01T00:00:00"
                      dontSendEmail: false
                content: null

  /campaign/send:
    post:
      tags:
        - Campaign
      summary: Send Campaign
      description: |
        Send the Campaign and publish the Credentials. Only Campaigns which have a Detail, Design, EmailTemplate and Credentials can be sent. Also, an already sent Campaign cannot be sent again.

        Details for the body of the request:

        - `id` id of the Campaign
      operationId: sendCampaign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IdRequest'
            example:
              id: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Operation is successful for 1 credentials."
                hasError: false
                validationErrors: []
                data: true
                content: null

  /campaign/schedule:
    post:
      tags:
        - Campaign
      summary: Schedule Campaign
      description: |
        Schedule Campaign to be sent at a specific date and time. Only Campaigns which have a Detail, Design, EmailTemplate and Credentials can be scheduled. Also, an already sent Campaign cannot be scheduled.

        **The schedule time should be given in regards to UTC Time Zone!**

        Details for the body of the request:

        - `id` id of the Campaign
        - `publishDate` the date to schedule the Campaign
      operationId: scheduleCampaign
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ScheduleRequest'
            example:
              id: "string"
              publishDate: "2023-02-15 22:40"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Operation is successful for 1 credentials."
                hasError: false
                validationErrors: []
                data: true
                content: null

  /recipient:
    post:
      tags:
        - Recipient
      summary: Add Recipients
      description: |
        Adds a member to your Recipients. This Recipient will be tied to the Credentials that are created with the same email address. However, if a Credential is created and there is no Recipient with a matching email address, the Recipient will be created automatically.
      operationId: addRecipients
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddRecipientsRequest'
            example:
              recipients:
                - name: "string"
                  email: "string"
                  attributes:
                    - id: "string"
                      value: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "string"
                hasError: false
                validationErrors: []
                data:
                  results:
                    - id: "string"
                      name: "string"
                      email: "string"
                      attributes:
                        - id: "string"
                          value: "string"
                content: null
    put:
      tags:
        - Recipient
      summary: Update Recipients
      description: |
        This endpoint can be used to update the `name`, `email` or `attributes` of your Recipients. The body allows to update multiple Recipients at once.
        All credentials which are connected to this Recipient (which have the same email) will be updated as well if `updateExistingCredentials` is set to `true`.
      operationId: updateRecipients
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateRecipientsRequest'
            example:
              recipients:
                - id: "string"
                  name: "string"
                  email: "string"
                  attributes:
                    - id: "string"
                      value: "string"
              updateExistingCredentials: false
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "The record has been successfully updated."
                hasError: false
                validationErrors: []
                data: false
                content: null

  /recipient/{recipient_id}:
    delete:
      tags:
        - Recipient
      summary: Delete Recipient
      description: Deletes the Recipient with the given `id` along with the Recipient's credentials. The `id` is passed in the parameters.
      operationId: deleteRecipient
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: recipient_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Recipient
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Record has been successfully deleted."
                hasError: false
                validationErrors: []
                data: true
                content: null

  /recipient/search:
    post:
      tags:
        - Recipient
      summary: Search Recipients
      description: |
        Returns the organizations Recipients in paginated format. The pagination is handled with the `startIndex` and `length` keys in the request body.
        There is one filtering option within the body:

        - `searchTerm` field is searched within the names and emails of the Recipients
      operationId: searchRecipients
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
            example:
              startIndex: 0
              length: 10
              searchTerm: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  results:
                    - id: "string"
                      name: "string"
                      email: "string"
                      externalID: null
                      attributes:
                        - id: "string"
                          value: "string"
                      profileUrl: "string"
                  total: 57
                content: null

  /credential/{credential_id}:
    get:
      tags:
        - Credential
      summary: Get Credential
      description: Returns the Credential of the given `id`. The `id` is passed to the parameters.
      operationId: getCredential
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: credential_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Credential
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  id: "string"
                  recipientId: "string"
                  createDate: "2023-02-02T22:24:25.486313"
                  issueDate: "2023-02-02T22:24:27.449559"
                  expireDate: null
                  name: "string"
                  email: "string"
                  certificateNO: "string"
                  status: 1
                  emailTracking: 2
                  isPublic: true
                  certificateImageLink: "string"
                  badgeImageLink: "string"
                  attributes:
                    - id: "string"
                      title: "string"
                      displayFormat: "string"
                      type: 1
                      value: "string"
                content: null
    put:
      tags:
        - Credential
      summary: Update Credential
      description: Updates the Credential corresponding to the given `id`. The endpoint can be used to update the `name`, `issueDate`, `expireDate` and custom `attributes` of the Credential.
      operationId: updateCredential
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: credential_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Credential
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CredentialUpdateRequest'
            example:
              name: "string"
              issueDate: "2023-01-01"
              expireDate: "2024-01-01"
              attributes:
                - id: "string"
                  value: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Credential updated successfully."
                hasError: false
                validationErrors: []
                data: "string"
                content: null
    delete:
      tags:
        - Credential
      summary: Delete Credential
      description: Deletes the credential corresponding to the given `id`. The `id` is passed in the parameters.
      operationId: deleteCredential
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: credential_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Credential
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Credential deleted successfully."
                hasError: false
                validationErrors: []
                data: false
                content: null

  /credential/search:
    post:
      tags:
        - Credential
      summary: Search Credentials
      description: |
        Returns the organizations Credentials in paginated format. The pagination is handled with the `startIndex` and `length` keys in the request body.
        There are three filtering options within the body:

        - `searchTerm` field is searched within the name and emails of the Credentials
        - `campaignIds` field is a string array used for filtering the Credentials which belong to the given Campaigns
        - `recipientIds` field is a string array used for filtering the Credentials which belong to the given Recipients
      operationId: searchCredentials
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CredentialSearchRequest'
            example:
              startIndex: 0
              length: 10
              status: 1
              campaignIds: ["string"]
              recipientIds: ["string"]
              searchTerm: "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  results:
                    - id: "string"
                      recipientId: "string"
                      createDate: "2023-02-14T08:39:35.474148"
                      issueDate: "2023-02-14T08:39:36.933201"
                      expireDate: null
                      name: "string"
                      email: "string"
                      certificateNO: "string"
                      status: 1
                      emailTracking: 2
                      isPublic: true
                      certificateImageLink: "string"
                      badgeImageLink: "string"
                  total: 208
                content: null

  /credential/publish:
    post:
      tags:
        - Credential
      summary: Publish Credentials
      description: |
        Takes the `id` values of the credentials and publishes them. An email will be sent if the Credential has an email address.

        One or more credentials can be published at once.
      operationId: publishCredentials
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublishRequest'
            example:
              ids:
                - "string"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "The certificate distribution process has been started so that \"1\" recipients in the list you selected will be forwarded to the recipient's emails."
                hasError: false
                validationErrors: []
                data: false
                content: null

  /credential/generatePDFLink/{credential_id_OR_certificate_no}:
    get:
      tags:
        - Credential
      summary: Generate PDF Link
      description: Generates the PDF Download Link and returns the link. The parameter can take in the `id` or the `certificateNO` of the Credential.
      operationId: generatePDFLink
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: credential_id_OR_certificate_no
          in: path
          required: true
          schema:
            type: string
          description: ID or certificateNO of the Credential
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  link: "string"
                content: null

  /attribute:
    post:
      tags:
        - Attribute
      summary: Add Attribute
      description: |
        The attribute has to be created before it can be added to any design. One attribute can be added to multiple designs.

        Details for the body of the request:

        - `title` is the title of the attribute which only the account owner will see
        - `type` is the data type for the value of the attribute and can have three different values:
          - 1 -> text
          - 2 -> date
          - 3 -> number
      operationId: addAttribute
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AttributeRequest'
            example:
              title: "string"
              type: 1
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Record has been successfully created"
                hasError: false
                validationErrors: []
                data: "string"
                content: null

  /attribute/{attribute_id}:
    put:
      tags:
        - Attribute
      summary: Update Attribute
      description: Updates the Attribute corresponding to the given `id`. The endpoint can be used to update the `title` and `type`.
      operationId: updateAttribute
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: attribute_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Attribute
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AttributeRequest'
            example:
              title: "string"
              type: 1
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "The record has been successfully updated."
                hasError: false
                validationErrors: []
                data: false
                content: null
    delete:
      tags:
        - Attribute
      summary: Delete Attribute
      description: Deletes the Attribute corresponding to the given `id`. The `id` is passed in the parameters.
      operationId: deleteAttribute
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - name: attribute_id
          in: path
          required: true
          schema:
            type: string
          description: ID of the Attribute
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: "Record has been successfully deleted."
                hasError: false
                validationErrors: []
                data: false
                content: null

  /attribute/search:
    post:
      tags:
        - Attribute
      summary: Search Attributes
      description: |
        Returns the organizations Attributes in paginated format. The pagination is handled with the `startIndex` and `length` keys in the request body.
        There are two filtering options within the body:

        - `searchTerm` field is searched within the titles of the Attributes
        - `types` field is a string array used for filtering the Attributes by `type`
          - `type` is the data type for the value of the attribute and can have three different values:
            - 1 -> text
            - 2 -> date
            - 3 -> number
      operationId: searchAttributes
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AttributeSearchRequest'
            example:
              startIndex: 10
              length: 10
              searchTerm: "string"
              types: [1, 2, 3]
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                message: null
                hasError: false
                validationErrors: []
                data:
                  results:
                    - id: "string"
                      title: "string"
                      displayFormat: "string"
                      type: 1
                  total: 18
                content: null

components:
  securitySchemes:
    secretKey:
      type: apiKey
      in: header
      name: secretKey
      description: Your organization's private API key. Find it at **Settings > API & Integrations** in the Sertifier app.

  parameters:
    ApiVersion:
      name: api-version
      in: header
      required: true
      schema:
        type: string
        default: '3.3'
      description: The API version. Current version is **3.3**. This value has to be set in every request.

  schemas:
    ApiResponse:
      type: object
      properties:
        message:
          type: string
          nullable: true
        hasError:
          type: boolean
        validationErrors:
          type: array
          items:
            type: string
        data: {}
        content:
          nullable: true

    SearchRequest:
      type: object
      properties:
        startIndex:
          type: integer
          description: Start index for pagination
        length:
          type: integer
          description: Number of results to return
        searchTerm:
          type: string
          description: Search term to filter results

    DesignSearchRequest:
      type: object
      properties:
        startIndex:
          type: integer
        length:
          type: integer
        type:
          type: integer
          description: "1 = certificate, 2 = badge"
        searchTerm:
          type: string

    CopyRequest:
      type: object
      required:
        - id
      properties:
        id:
          type: string
          description: ID of the entity to copy

    DetailRequest:
      type: object
      properties:
        type:
          type: integer
          description: "Detail type enum (0=Field Event, 1=Online Event, 2=Class Course, 3=Online Course, 4=Webinar, 5=Achievement, 6=License, 7=Appreciation, 8=Promotional Course, 9=Membership, 10=Graduation, 11=Hybrid Event, 12=Hybrid Course)"
        title:
          type: string
        description:
          type: string
        durationNumber:
          type: integer
        durationType:
          type: integer
          description: "Duration type enum (1=Hour, 2=Day, 3=Week, 4=Month, 5=Year, 6=Minute)"
        cost:
          type: integer
          description: "Cost enum (0=Free, 1=Paid, 2=NA)"
        expireDate:
          type: string
          format: date
          nullable: true
        expireDateNumber:
          type: integer
          nullable: true
        expireDateType:
          type: integer
          nullable: true
          description: "DurationType enum value"
        level:
          type: integer
          description: "Level enum (0=Beginner, 1=Intermediate, 2=Advanced, 3=Experienced, 4=Professional, 5=NA)"
        earningCriteria:
          type: string
          nullable: true
          description: "Earning criteria, can be HTML"
        dontSendExpireDateEmail:
          type: boolean
        skills:
          type: array
          items:
            $ref: '#/components/schemas/Skill'
        expiryReminderDays:
          type: array
          items:
            type: integer
          description: "List of days before expire date to send reminders (max 3)"

    Skill:
      type: object
      properties:
        skillId:
          type: string
          description: "Skill ID from /detail/searchSkills, leave blank for custom skills"
        title:
          type: string
        languageCode:
          type: string
          description: "Must be 'en' or 'tr'"

    SkillSearchRequest:
      type: object
      properties:
        startIndex:
          type: integer
        length:
          type: integer
        searchTerm:
          type: string
        language:
          type: string
          description: "'en' or 'tr'"

    CampaignRequest:
      type: object
      properties:
        title:
          type: string
        detailId:
          type: string
        badgeId:
          type: string
          nullable: true
        designId:
          type: string
          nullable: true
        emailTemplateId:
          type: string
        emailFromName:
          type: string
        emailSubject:
          type: string
        emailfromAddress:
          type: string
          nullable: true
        privateCampaign:
          type: boolean

    CampaignSearchRequest:
      type: object
      properties:
        startIndex:
          type: integer
        length:
          type: integer
        status:
          type: array
          items:
            type: integer
          description: "Campaign status enum values (0=NoEntry, 1=Draft, 2=Scheduled, 3=Sent)"
        searchTerm:
          type: string

    AddCredentialsRequest:
      type: object
      properties:
        credentials:
          type: array
          items:
            $ref: '#/components/schemas/CredentialInput'

    CredentialInput:
      type: object
      properties:
        campaignId:
          type: string
        name:
          type: string
        email:
          type: string
        issueDate:
          type: string
          format: date
          description: "Issue date, defaults to time of request if omitted"
        expireDate:
          type: string
          format: date
          nullable: true
        quickPublish:
          type: boolean
          description: "If true, credential is published immediately"
        externalId:
          type: string
          nullable: true
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/AttributeValue'
        dontSendEmail:
          type: boolean
          description: "If true, no email notification is sent. Default is false"

    AttributeValue:
      type: object
      properties:
        id:
          type: string
        value:
          type: string

    IdRequest:
      type: object
      required:
        - id
      properties:
        id:
          type: string

    ScheduleRequest:
      type: object
      required:
        - id
        - publishDate
      properties:
        id:
          type: string
        publishDate:
          type: string
          description: "Schedule date in UTC (format: YYYY-MM-DD HH:mm)"

    AddRecipientsRequest:
      type: object
      properties:
        recipients:
          type: array
          items:
            $ref: '#/components/schemas/RecipientInput'

    RecipientInput:
      type: object
      properties:
        name:
          type: string
        email:
          type: string
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/AttributeValue'

    UpdateRecipientsRequest:
      type: object
      properties:
        recipients:
          type: array
          items:
            $ref: '#/components/schemas/RecipientUpdateInput'
        updateExistingCredentials:
          type: boolean
          description: "If true, all credentials connected to this Recipient will be updated as well"

    RecipientUpdateInput:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        email:
          type: string
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/AttributeValue'

    CredentialUpdateRequest:
      type: object
      properties:
        name:
          type: string
        issueDate:
          type: string
          format: date
        expireDate:
          type: string
          format: date
          nullable: true
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/AttributeValue'

    CredentialSearchRequest:
      type: object
      properties:
        startIndex:
          type: integer
        length:
          type: integer
        status:
          type: integer
        campaignIds:
          type: array
          items:
            type: string
          description: "Filter by Campaign IDs"
        recipientIds:
          type: array
          items:
            type: string
          description: "Filter by Recipient IDs"
        searchTerm:
          type: string

    PublishRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string

    AttributeRequest:
      type: object
      properties:
        title:
          type: string
        type:
          type: integer
          description: "Attribute type (1=text, 2=date, 3=number)"

    AttributeSearchRequest:
      type: object
      properties:
        startIndex:
          type: integer
        length:
          type: integer
        searchTerm:
          type: string
        types:
          type: array
          items:
            type: integer
          description: "Filter by attribute types (1=text, 2=date, 3=number)"
