openapi: 3.0.3

info:
  title: Retrieve and List Municipalities and their forms
  description: >
    API providing a list of municipalities and the forms available for each municipality,
    including form metadata and availability information.

    This API is secured using an API key sent in the request header `x-api-key`.
  version: 0.2.0
  contact:
    name: CumulusPro Support
    email: support@cumuluspro.com
  license:
    name: Proprietary

tags:
  - name: Municipalities
    description: municipality-related operations

servers:
  - url: https://api.gemeindeconnect.ch/extension
    description: Production server
  - url: https://api-dev.gemeindeconnect.ch/extension
    description: Test server

security:
  - ApiKeyAuth: []

paths:
  /municipalities:
    get:
      tags:
        - Municipalities and Forms
      summary: Get list of municipalities with available forms
      description: >
        Returns all municipalities and the forms available for each municipality.
      operationId: getMunicipalities
      parameters:
        - $ref: "#/components/parameters/CorrelationIdParam"
      responses:
        "200":
          description: Successful response
          headers:
            x-correlation-id:
              $ref: "#/components/headers/CorrelationIdHeader"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MunicipalityList"
              examples:
                noMunicipalities:
                  summary: No municipalities available
                  description: The system currently has no municipalities configured.
                  value:
                    items: []
                oneMunicipalityNoActiveForms:
                  summary: One municipality with no active forms
                  description: The municipality exists, but none of its forms are active (inactive).
                  value:
                    items:
                      - municipalityId: 303
                        municipalityName: "Grenchen"
                        forms:
                          - formId: "3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                            formName:
                              de: "Niederlassungsbescheinigung bestellen"
                            formDescription:
                              de: "<p>Bestellen Sie hier Ihre Niederlassungsbescheinigung.</p>"
                            status: "inactive"
                            tags:
                              - "Einwohnerkontrolle"
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                          - formId: "16165cd6-6f18-435f-a2f9-e088a6f13fa9"
                            formName:
                              de: "Ratenzahlung / Stundung für die definitiven Gemeindesteuern beantragen"
                            formDescription:
                              de: "<p>Bestellen Sie hier Ihre Ratenzahlung.</p>"
                            status: "inactive"
                            tags:
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/16165cd6-6f18-435f-a2f9-e088a6f13fa9"
                          - formId: "72db1819-a7c2-4874-9fe2-bf6c821e8bad"
                            formName:
                              de: "Adressauskunft bestellen"
                            formDescription:
                              de: "<p>Adressauskunft online bestellen.</p>"
                            status: "inactive"
                            tags: []
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/72db1819-a7c2-4874-9fe2-bf6c821e8bad"

                oneMunicipalityOneForm:
                  summary: One municipality with one active form
                  description: The municipality has exactly one active form; others are not active.
                  value:
                    items:
                      - municipalityId: 303
                        municipalityName: "Grenchen"
                        forms:
                          - formId: "3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                            formName:
                              de: "Niederlassungsbescheinigung bestellen"
                            formDescription:
                              de: "<p>Bestellen Sie hier Ihre Niederlassungsbescheinigung.</p>"
                            status: "active"
                            tags:
                              - "Einwohnerkontrolle"
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                          - formId: "16165cd6-6f18-435f-a2f9-e088a6f13fa9"
                            formName:
                              de: "Ratenzahlung / Stundung für die definitiven Gemeindesteuern beantragen"
                            formDescription:
                              de: "<p>Bestellen Sie hier Ihre Ratenzahlung.</p>"
                            status: "inactive"
                            tags:
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/16165cd6-6f18-435f-a2f9-e088a6f13fa9"

                oneMunicipalityTwoForms:
                  summary: One municipality with two forms
                  description: One active and one inactive form for the same municipality.
                  value:
                    items:
                      - municipalityId: 303
                        municipalityName: "Grenchen"
                        forms:
                          - formId: "3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                            formName:
                              de: "Niederlassungsbescheinigung bestellen"
                            formDescription:
                              de: "<p>Bestellen Sie hier Ihre Niederlassungsbescheinigung.</p>"
                            status: "active"
                            tags:
                              - "Einwohnerkontrolle"
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                          - formId: "e0d008d9-60aa-4ed2-8ca7-ac8fd7ad0a41"
                            formName:
                              de: "Bescheinigung zum auswärtigen Aufenthalt bestellen"
                            formDescription:
                              de: "<p>Bescheinigung zum auswärtigen Aufenthalt online bestellen.</p>"
                            status: "inactive"
                            tags:
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/e0d008d9-60aa-4ed2-8ca7-ac8fd7ad0a41"

                twoMunicipalitiesMixedForms:
                  summary: Two municipalities with mixed forms and statuses
                  description: Two municipalities, different number of forms; at least two active and one inactive per municipality.
                  value:
                    items:
                      - municipalityId: 303
                        municipalityName: "Grenchen"
                        forms:
                          - formId: "3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                            formName:
                              de: "Niederlassungsbescheinigung bestellen"
                            formDescription:
                              de: "<p>Bestellen Sie hier Ihre Niederlassungsbescheinigung.</p>"
                            status: "active"
                            tags:
                              - "Einwohnerkontrolle"
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                          - formId: "16165cd6-6f18-435f-a2f9-e088a6f13fa9"
                            formName:
                              de: "Ratenzahlung / Stundung für die definitiven Gemeindesteuern beantragen"
                            formDescription:
                              de: "<p>Bestellen Sie hier Ihre Ratenzahlung.</p>"
                            status: "active"
                            tags:
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/16165cd6-6f18-435f-a2f9-e088a6f13fa9"
                          - formId: "72db1819-a7c2-4874-9fe2-bf6c821e8bad"
                            formName:
                              de: "Adressauskunft bestellen"
                            formDescription:
                              de: "<p>Adressauskunft online bestellen.</p>"
                            status: "inactive"
                            tags: []
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/72db1819-a7c2-4874-9fe2-bf6c821e8bad"

                      - municipalityId: 261
                        municipalityName: "Schwyz"
                        forms:
                          - formId: "3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                            formName:
                              de: "Niederlassungsbescheinigung bestellen"
                            formDescription:
                              de: "<p>Bestellen Sie hier Ihre Niederlassungsbescheinigung.</p>"
                            status: "active"
                            tags:
                              - "Einwohnerkontrolle"
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/261/3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                          - formId: "e0d008d9-60aa-4ed2-8ca7-ac8fd7ad0a41"
                            formName:
                              de: "Bescheinigung zum auswärtigen Aufenthalt bestellen"
                            formDescription:
                              de: "<p>Bescheinigung zum auswärtigen Aufenthalt online bestellen.</p>"
                            status: "active"
                            tags:
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/261/e0d008d9-60aa-4ed2-8ca7-ac8fd7ad0a41"
                          - formId: "16165cd6-6f18-435f-a2f9-e088a6f13fa9"
                            formName:
                              de: "Ratenzahlung / Stundung für die definitiven Gemeindesteuern beantragen"
                            formDescription:
                              de: "<p>Bestellen Sie hier Ihre Ratenzahlung.</p>"
                            status: "inactive"
                            tags:
                              - "GemeindeConnect final"
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/261/16165cd6-6f18-435f-a2f9-e088a6f13fa9"
                          - formId: "72db1819-a7c2-4874-9fe2-bf6c821e8bad"
                            formName:
                              de: "Adressauskunft bestellen"
                            formDescription:
                              de: "<p>Adressauskunft online bestellen.</p>"
                            status: "active"
                            tags: []
                            formUrl: "https://schwyz.cumuluspro.net/workflow-forms/261/72db1819-a7c2-4874-9fe2-bf6c821e8bad"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/TooManyRequests"
        "500":
          $ref: "#/components/responses/InternalServerError"
  /municipalities/{municipalityId}:
    get:
      tags:
        - Single Muncipality and Forms
      summary: Get a single municipality with available forms
      description: Returns one municipality and the forms available for the municipality.
      operationId: getMunicipalityById
      parameters:
        - name: municipalityId
          in: path
          description: Unique identifier of the municipality.
          required: true
          schema:
            type: integer
            format: int32
          example: 303
        - $ref: "#/components/parameters/CorrelationIdParam"
      responses:
        "200":
          description: Successful response
          headers:
            x-correlation-id:
              $ref: "#/components/headers/CorrelationIdHeader"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Municipality"
              examples:
                municipality303:
                  summary: Example municipality 303
                  value:
                    municipalityId: 303
                    municipalityName: "Grenchen"
                    forms:
                      - formId: "3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                        formName:
                          de: "Niederlassungsbescheinigung bestellen"
                        formDescription:
                          de: "<p>Bestellen Sie hier Ihre Niederlassungsbescheinigung.</p>"
                        status: "active"
                        tags:
                          - "Einwohnerkontrolle"
                          - "GemeindeConnect final"
                        formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
                      - formId: "72db1819-a7c2-4874-9fe2-bf6c821e8bad"
                        formName:
                          de: "Adressauskunft bestellen"
                        formDescription:
                          de: "<p>Adressauskunft online bestellen.</p>"
                        status: "inactive"
                        tags: []
                        formUrl: "https://schwyz.cumuluspro.net/workflow-forms/303/72db1819-a7c2-4874-9fe2-bf6c821e8bad"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"  
        "429":
          $ref: "#/components/responses/TooManyRequests"
        "500":
          $ref: "#/components/responses/InternalServerError"


components:
  headers:
    CorrelationIdHeader:
      description: Correlation ID for tracing the request across systems.
      schema:
        type: string
  parameters:
    CorrelationIdParam:
      name: x-correlation-id
      in: header
      description: Optional correlation ID provided by the client. If not provided, the server will generate one.
      required: false
      schema:
        type: string
      example: "b7e2f9a0c8a14f3db8c7c5f4a1b2c3d4"
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key required for server-to-server access.
  responses:
    NotFound:
      description: The specified municipality was not found.
      headers:
        x-correlation-id:
          $ref: "#/components/headers/CorrelationIdHeader"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            municipalityNotFound:
              summary: Municipality not found
              value:
                code: "NotFound"
                message: "The specified municipality was not found."
                correlationId: "b7e2f9a0c8a14f3db8c7c5f4a1b2c3d4"
    Unauthorized:
      description: A valid API key (x-api-key) is required to access this resource.
      headers:
        x-correlation-id:
          $ref: "#/components/headers/CorrelationIdHeader"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            missingToken:
              summary: A valid API key (x-api-key) is required to access this resource.
              value:
                code: "Unauthorized"
                message: "A valid API key (x-api-key) is required to access this resource."
                correlationId: "b7e2f9a0c8a14f3db8c7c5f4a1b2c3d4"

    Forbidden:
      description: Authenticated but not authorized to access this resource.
      headers:
        x-correlation-id:
          $ref: "#/components/headers/CorrelationIdHeader"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            insufficientPermissions:
              summary: Insufficient permissions
              value:
                code: "Forbidden"
                message: "You do not have permission to access this resource."
                correlationId: "b7e2f9a0c8a14f3db8c7c5f4a1b2c3d4"
    BadRequest:
      description: Invalid request
      headers:
        x-correlation-id:
          $ref: "#/components/headers/CorrelationIdHeader"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            invalidRequest:
              summary: Invalid request
              value:
                code: "InvalidRequest"
                message: "One or more request parameters are invalid."
                correlationId: "b7e2f9a0c8a14f3db8c7c5f4a1b2c3d4"

    InternalServerError:
      description: Internal server error
      headers:
        x-correlation-id:
          $ref: "#/components/headers/CorrelationIdHeader"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            unexpectedError:
              summary: Unexpected error
              value:
                code: "InternalServerError"
                message: "An unexpected error occurred."
                correlationId: "f1c2d3e4a5b6478899aabbccddeeff00"

    TooManyRequests:
      description: Too many requests
      headers:
        x-correlation-id:
          $ref: "#/components/headers/CorrelationIdHeader"
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            oneOf:
              - type: string
              - type: integer
          example: 30
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            rateLimited:
              summary: Rate limit exceeded
              value:
                code: "TooManyRequests"
                message: "Rate limit exceeded. Please try again later."
                correlationId: "b7e2f9a0c8a14f3db8c7c5f4a1b2c3d4"

  schemas:
    MunicipalityList:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/Municipality"
      required:
        - items

    Municipality:
      type: object
      additionalProperties: false
      description: municipality (municipality) with its available forms.
      properties:
        municipalityId:
          type: integer
          format: int32
          description: Unique identifier of the municipality.
          example: 303
        municipalityName:
          type: string
          description: Official name of the municipality.
          example: "Grenchen"
        forms:
          type: array
          items:
            $ref: "#/components/schemas/Form"
      required:
        - municipalityId
        - municipalityName
        - forms

    Form:
      type: object
      additionalProperties: false
      properties:
        formId:
          type: string
          format: uuid
          example: "3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
        formName:
          type: object
          description: Localized form name keyed by language code (e.g. de, en, fr).
          additionalProperties:
            type: string
          example:
            de: "Niederlassungsbescheinigung bestellen"
            en: "Order a residence certificate"
        formDescription:
          type: object
          description: Localized HTML description keyed by language code.
          additionalProperties:
            type: string
          example:
            de: "<p>Bestellen Sie hier Ihre Niederlassungsbescheinigung.</p>"
            en: "<p>Order your residence certificate here.</p>"
        status:
          type: string
          description: Current lifecycle status of the form for this municipality.
          enum:
            - active
            - inactive
          example: "active"
        tags:
          type: array
          description: Optional classification tags for filtering/grouping.
          items:
            type: string
          example:
            - "einwohnerkontrolle"
        formUrl:
          type: string
          format: uri
          example: "https://schwyz.cumuluspro.net/workflow-forms/303/3c0c8705-37cc-4c59-80e7-387b0fe9c0af"
      required:
        - formId
        - formName
        - formDescription
        - status
        - formUrl

    ErrorResponse:
      type: object
      additionalProperties: false
      description: Standard error response.
      properties:
        code:
          type: string
          description: Machine-readable error code.
          example: "InvalidRequest"
        message:
          type: string
          description: Human-readable error message.
          example: "municipalityId must be an integer."
        correlationId:
          type: string
          description: Correlation ID for troubleshooting and tracing across systems.
          example: "b7e2f9a0c8a14f3db8c7c5f4a1b2c3d4"
      required:
        - code
        - message