openapi: 3.0.0
info:
  title: Certificate
  version: 2.0.0
  description: >
    A **Certificate** represents a document proving that a resource (person,
    equipment, work environment,

    substance, role, work group, office, PPE, or supplier) has fulfilled a
    compliance requirement.


    Certificates are the proof of compliance: each certificate documents that a
    resource has completed

    a requirement (training course, medical examination, maintenance, etc.).


    Use this API to:

    - Find certificates for a person (filter by `resource_id` with the
    `person_id`)

    - Find certificates by requirement type (filter by `action_type`)

    - Create a new certificate to document the completion of a requirement


    Creating a certificate does **not** automatically update the compliance
    schedule.

    To update the compliance status, you must create a CertificateAction that
    links

    the certificate to the specific action. Without the CertificateAction, the
    certificate

    exists but has no effect on the compliance schedule.
servers:
  - url: http://service.4hse.com/
security:
  - OAuth2: []
  - AccessToken: []
webhooks:
  CERTIFICATE::CREATE:
    post:
      summary: Certificate created
      security: []
      description: |
        Triggered when a new certificate is created.
      requestBody:
        description: The newly created certificate
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Certificate"
            example:
              certificate_id: f6a7b8c9-d0e1-2f3a-4b5c-6d7e8f9a0b1c
              date_release: 2024-01-15
              date_expire: 2029-01-15
              name: Fire Safety Training Certificate
              action_type: TRAINING
              resource_id: e3a1f5d2-8c4b-4e7a-9f6d-2b1c3d4e5f6a
              tenant_id: b5a7d602-3fc9-4e2a-9d1a-6e5b4c8f7a01
              validity_unit: YEAR
              validity: 5
      responses:
        "200":
          description: Acknowledgment of the webhook event
  CERTIFICATE::UPDATE:
    post:
      summary: Certificate updated
      security: []
      description: |
        Triggered when a certificate is updated. Provides the certificate ID and
        old/new values for each updated field.
      requestBody:
        description: Updated certificate with old and new values for changed fields
        content:
          application/json:
            schema:
              type: object
              properties:
                entity_id:
                  type: string
                  format: uuid
                  description: The certificate_id of the updated certificate.
                updated_fields:
                  type: object
                  additionalProperties:
                    type: object
                    properties:
                      old: {}
                      new: {}
                  description: Each key is an updated field name, with its old and new values.
              required:
                - entity_id
                - updated_fields
            example:
              entity_id: f6a7b8c9-d0e1-2f3a-4b5c-6d7e8f9a0b1c
              updated_fields:
                date_expire:
                  old: 2029-01-15
                  new: 2030-01-15
      responses:
        "200":
          description: Acknowledgment of the webhook event
  CERTIFICATE::DELETE:
    post:
      summary: Certificate deleted
      security: []
      description: |
        Triggered when a certificate is deleted.
      requestBody:
        description: The deleted certificate
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Certificate"
            example:
              certificate_id: f6a7b8c9-d0e1-2f3a-4b5c-6d7e8f9a0b1c
              name: Fire Safety Training Certificate
              action_type: TRAINING
              resource_id: e3a1f5d2-8c4b-4e7a-9f6d-2b1c3d4e5f6a
              tenant_id: b5a7d602-3fc9-4e2a-9d1a-6e5b4c8f7a01
      responses:
        "200":
          description: Acknowledgment of the webhook event
paths:
  /v2/certificate/index:
    post:
      summary: index
      operationId: indexCertificate
      tags:
        - Certificates
      description: >
        Returns a paginated list of certificates.


        Most useful filters:

        - `resource_id` (person_id): all certificates for a person

        - `action_type`: certificates by requirement type (e.g. `TRAINING` for
        training)

        - `tenant_id` (project_id): all certificates in a company


        The response includes the name and type of the resource the certificate
        is issued to,

        and the project name.
      requestBody:
        description: Parameters for searching certificates
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CertificateIndexParams"
            example:
              filter:
                resource_id: e3a1f5d2-8c4b-4e7a-9f6d-2b1c3d4e5f6a
                action_type: TRAINING
              per-page: 20
              page: 1
              sort: -date_expire
      responses:
        "200":
          description: List of certificates
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ViewCertificate"
              example:
                - certificate_id: f6a7b8c9-d0e1-2f3a-4b5c-6d7e8f9a0b1c
                  date_release: 2024-01-15
                  date_expire: 2029-01-15
                  name: Fire Safety Training Certificate
                  action_type: TRAINING
                  resource_id: e3a1f5d2-8c4b-4e7a-9f6d-2b1c3d4e5f6a
                  resource_type: PERSON
                  resource_name: Smith John
                  warning: 0
                  tenant_id: b5a7d602-3fc9-4e2a-9d1a-6e5b4c8f7a01
                  subtenant_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  validity_unit: YEAR
                  validity: 5
                  project_name: Acme Construction Ltd
          headers:
            X-Pagination-Current-Page:
              schema:
                type: integer
              description: Current page
            X-Pagination-Page-Count:
              schema:
                type: integer
              description: Total number of pages
            X-Pagination-Per-Page:
              schema:
                type: integer
              description: Number of items per page
            X-Pagination-Total-Count:
              schema:
                type: integer
              description: Total number of items
  /v2/certificate/view/{id}:
    get:
      summary: view
      operationId: viewCertificate
      tags:
        - Certificates
      description: |
        Retrieves a single certificate by its ID.
      parameters:
        - name: id
          in: path
          description: The certificate_id to retrieve.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Certificate found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ViewCertificate"
              example:
                certificate_id: f6a7b8c9-d0e1-2f3a-4b5c-6d7e8f9a0b1c
                date_release: 2024-01-15
                date_expire: 2029-01-15
                name: Fire Safety Training Certificate
                action_type: TRAINING
                resource_id: e3a1f5d2-8c4b-4e7a-9f6d-2b1c3d4e5f6a
                resource_type: PERSON
                resource_name: Smith John
                warning: 0
                tenant_id: b5a7d602-3fc9-4e2a-9d1a-6e5b4c8f7a01
                subtenant_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                validity_unit: YEAR
                validity: 5
                project_name: Acme Construction Ltd
        "404":
          description: Certificate not found
  /v2/certificate/verify:
    get:
      summary: verify
      operationId: verifyCertificate
      tags:
        - Certificates
      description: >
        Returns a single certificate (same payload as `view`) plus
        `attachment_urls`:

        pre-signed URLs for every certificate attachment, so the public
        (unauthenticated)

        verification page can display/download them.


        Accessible both by authenticated clients and via UrlSign: pass the
        `urlsign` query

        parameter authorizing access (handled by AclFilter). The pre-signed
        attachment URLs

        reuse the remaining TTL of that token; for authenticated calls a default
        TTL is used.
      parameters:
        - name: id
          in: query
          description: The certificate_id to verify.
          required: true
          schema:
            type: string
            format: uuid
        - name: urlsign
          in: query
          description: UrlSign token authorizing public access. Optional for authenticated
            clients.
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Certificate found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CertificateVerify"
        "404":
          description: Certificate not found
  /v2/certificate/create:
    post:
      summary: create
      operationId: createCertificate
      tags:
        - Certificates
      description: >
        Creates a new certificate.


        Requires `date_release`, `name`, `action_type`, `resource_id`, and
        `tenant_id` (project_id).

        The `certificate_id` is auto-generated if not provided.


        The `resource_id` is the ID of the resource the certificate is issued
        to.

        What to pass depends on the `action_type`:

        - For `TRAINING`, `HEALTH`, `PER`: pass the `person_id`

        - For `MAINTENANCE`: pass the `office_equipment_id`,
        `office_work_environment_id`, or other resource ID

        - For `CHECK`: any resource type


        After creating the certificate, create a **CertificateAction** to link
        it to the specific action.

        Without this link, the certificate exists but has no effect on the
        compliance schedule.


        To attach a file (e.g. the PDF of the certificate), upload the file via
        the Attachment API

        and then create an EntityAttachment to link it to the certificate.
      requestBody:
        description: Certificate object to be created
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Certificate"
            example:
              date_release: 2024-01-15
              date_expire: 2029-01-15
              name: Fire Safety Training Certificate
              action_type: TRAINING
              resource_id: e3a1f5d2-8c4b-4e7a-9f6d-2b1c3d4e5f6a
              tenant_id: b5a7d602-3fc9-4e2a-9d1a-6e5b4c8f7a01
              validity_unit: YEAR
              validity: 5
      responses:
        "201":
          description: Certificate created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Certificate"
              example:
                certificate_id: f6a7b8c9-d0e1-2f3a-4b5c-6d7e8f9a0b1c
                date_release: 2024-01-15
                date_expire: 2029-01-15
                name: Fire Safety Training Certificate
                action_type: TRAINING
                resource_id: e3a1f5d2-8c4b-4e7a-9f6d-2b1c3d4e5f6a
                tenant_id: b5a7d602-3fc9-4e2a-9d1a-6e5b4c8f7a01
                validity_unit: YEAR
                validity: 5
  /v2/certificate/update/{id}:
    put:
      summary: update
      operationId: updateCertificate
      tags:
        - Certificates
      description: |
        Updates an existing certificate.
      parameters:
        - name: id
          in: path
          description: The certificate_id to update.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: Certificate fields to update
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Certificate"
            example:
              name: Fire Safety Training Certificate - Renewed
              date_expire: 2030-01-15
      responses:
        "200":
          description: Certificate updated successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Certificate"
              example:
                certificate_id: f6a7b8c9-d0e1-2f3a-4b5c-6d7e8f9a0b1c
                name: Fire Safety Training Certificate - Renewed
                date_expire: 2030-01-15
        "404":
          description: Certificate not found
  /v2/certificate/delete/{id}:
    delete:
      summary: delete
      operationId: deleteCertificate
      tags:
        - Certificates
      description: >
        Deletes a certificate.


        If `force=false` (default), the response lists child entities
        (CertificateAction links, EntityAttachment links).

        If `force=true`, the certificate and all related entities are deleted.
      parameters:
        - name: id
          in: path
          description: The certificate_id to delete.
          required: true
          schema:
            type: string
            format: uuid
        - name: force
          in: query
          description: If true, deletes the certificate and all child entities. If false,
            returns a preview of affected entities.
          schema:
            type: boolean
            default: false
      responses:
        "204":
          description: Certificate deleted successfully
        "400":
          description: Preview of entities that would be deleted (returned when force=false)
components:
  schemas:
    Certificate:
      type: object
      properties:
        certificate_id:
          type: string
          format: uuid
          description: Unique identifier of the certificate. Auto-generated if not
            provided on creation.
        date_release:
          type: string
          format: date
          description: Issue date of the certificate.
        date_expire:
          type: string
          format: date
          description: Expiration date of the certificate. If not specified, the
            certificate does not expire. When linked to an action via
            CertificateAction, the expiration can be inherited from the action's
            validity settings.
        name:
          type: string
          maxLength: 255
          description: Descriptive name of the certificate.
        note:
          type: string
          description: Free-text notes.
        action_type:
          type: string
          enum:
            - TRAINING
            - MAINTENANCE
            - HEALTH
            - CHECK
            - PER
          description: |
            The type of requirement this certificate relates to:
            - `TRAINING`: training course
            - `HEALTH`: medical surveillance
            - `PER`: personal protective equipment
            - `CHECK`: check procedure
            - `MAINTENANCE`: maintenance
        resource_id:
          type: string
          format: uuid
          description: >
            The ID of the resource this certificate is issued to. What to pass
            depends on the `action_type`:

            - For `TRAINING`, `HEALTH`, `PER`: pass the `person_id`

            - For `EQUIPMENT`: pass the `office_equipment_id`

            - For `WORK_ENVIRONMENT`: pass the `office_work_environment_id`

            - For `SUBSTANCE`: pass the `office_substance_id`

            - For `ROLE`: pass the `office_role_id`

            - For `WORK_GROUP`: pass the `work_group_id`

            - For `OFFICE`: pass the `office_id`

            - For `PPE`: pass the `material_item_id`

            - For `UNIT`: pass the `unit_id` (supplier)

            If unknown, search via the corresponding API (e.g. Person index for
            people).
        data:
          type: object
          description: Additional structured data in JSON format. The content varies
            depending on the `action_type` of the certificate (e.g. medical
            examination results for HEALTH, course details for TRAINING, etc.).
        status:
          type: string
          enum:
            - draft
            - valid
            - revoked
            - rejected
          default: valid
          description: >
            Lifecycle status of the certificate:

            - `draft`: not yet finalized; does not affect the compliance
            schedule

            - `valid`: active and effective

            - `revoked`: revoked after issuance

            - `rejected`: not approved
        time_precision:
          type: integer
          enum:
            - 0
            - 1
          default: 0
          description: >
            - `1`: `date_release` and `date_expire` carry a time component
            (15-minute granularity) and expiration is evaluated with datetime
            precision

            - `0` (default): only the date is used
        warning:
          type: integer
          enum:
            - 0
            - 1
          description: |
            - `1`: the certificate has an active warning
            - `0`: no warning
        tenant_id:
          type: string
          format: uuid
          description: The project (company) this certificate belongs to. Pass the
            `project_id` obtained from the Project API.
        validity_unit:
          type: string
          enum:
            - YEAR
            - MONTH
            - DAY
          description: Unit for the certificate validity period. Used together with
            `validity`.
        validity:
          type: integer
          description: Number of validity units. Together with `validity_unit`, defines
            the certificate validity period.
      required:
        - date_release
        - name
        - action_type
        - resource_id
    ViewCertificate:
      type: object
      properties:
        certificate_id:
          type: string
          format: uuid
          description: Unique identifier of the certificate.
        date_release:
          type: string
          format: date
          description: Issue date of the certificate.
        date_expire:
          type: string
          format: date
          description: Expiration date. May be inherited from the linked action's validity
            settings.
        name:
          type: string
          maxLength: 255
          description: Descriptive name of the certificate.
        note:
          type: string
          description: Free-text notes.
        action_type:
          type: string
          enum:
            - TRAINING
            - MAINTENANCE
            - HEALTH
            - CHECK
            - PER
          description: Type of requirement this certificate relates to.
        resource_id:
          type: string
          format: uuid
          description: The ID of the resource this certificate is issued to.
        resource_type:
          type: string
          maxLength: 50
          enum:
            - PERSON
            - MATERIAL_ITEM
            - ROLE
            - WORK_GROUP
            - WORK_ENVIRONMENT
            - SUBSTANCE
            - EQUIPMENT
            - OFFICE
            - UNIT
          description: The type of the resource this certificate is issued to.
        resource_name:
          type: string
          maxLength: 255
          description: Display name of the resource this certificate is issued to.
        data:
          type: object
          description: Additional structured data. Content varies by `action_type`.
        status:
          type: string
          enum:
            - draft
            - valid
            - revoked
            - rejected
          description: Lifecycle status of the certificate (draft, valid, revoked,
            rejected). Can be used as a filter.
        time_precision:
          type: integer
          enum:
            - 0
            - 1
          description: Whether `date_release`/`date_expire` carry a time component
            (15-minute granularity) and expiration is evaluated with datetime
            precision (`1`) or only the date is used (`0`).
        warning:
          type: integer
          enum:
            - 0
            - 1
          description: Whether the certificate has an active warning.
        tenant_id:
          type: string
          format: uuid
          description: The project (company) this certificate belongs to.
        subtenant_id:
          type: string
          format: uuid
          description: The office associated with this certificate, derived from the
            linked action.
        subtenant_type:
          type: string
          maxLength: 50
          description: Type of the associated office.
        validity_unit:
          type: string
          enum:
            - YEAR
            - MONTH
            - DAY
          description: Unit for the certificate validity period.
        validity:
          type: integer
          description: Number of validity units.
        project_name:
          type: string
          description: Name of the project (company).
    CertificateVerify:
      description: Certificate payload (as `view`) plus pre-signed attachment URLs.
      allOf:
        - $ref: "#/components/schemas/ViewCertificate"
        - type: object
          properties:
            attachment_urls:
              type: array
              description: Pre-signed URLs for the certificate attachments.
              items:
                $ref: "#/components/schemas/AttachmentUrl"
    AttachmentUrl:
      type: object
      properties:
        url:
          type: string
          description: Pre-signed URL (`/v2/attachment/verify/...?urlsign=...`) to
            display/download the attachment.
        name:
          type: string
          description: File name of the attachment.
        mime_type:
          type: string
          nullable: true
          description: MIME type of the attachment, when known.
        purpose:
          type: string
          nullable: true
          description: Purpose/role of the attachment, when set.
    CertificateIndexParams:
      type: object
      properties:
        filter:
          $ref: "#/components/schemas/ViewCertificate"
        per-page:
          type: integer
          minimum: 1
          default: 100
        page:
          type: integer
          minimum: 1
          default: 1
        sort:
          type: string
          description: Field to sort by. Prefix with minus for descending order (e.g.
            "-date_expire").
          enum:
            - date_release
            - date_expire
            - name
            - action_type
      example:
        filter:
          resource_id: e3a1f5d2-8c4b-4e7a-9f6d-2b1c3d4e5f6a
          action_type: TRAINING
        per-page: 50
        page: 1
        sort: -date_expire
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        password:
          tokenUrl: https://auth.4hse.com/realms/4hse/protocol/openid-connect/token
          scopes: {}
    AccessToken:
      type: apiKey
      in: query
      name: access-token
