openapi: 3.1.0

security: []

info:
    title: Advanced API
    version: 6.10.0
    description: |
        Gain fine-grained control over the conversion process, letting you convert many documents in bulk and check their status during the conversion process. Reliably process the harmonization of documents from various sources and prepare them optimally for your intended purpose. The Advanced API also lets you convert files larger than 100 MB with no upper size limit.

servers:
    - url: 'http://{domain}:13033/conversion/v1.0/rest'
      description: Production server
      variables:
        domain:
          description: |
            The base URL for the API requests. Use the IP address of the computer where the Conversion Service Configurator is running. If it's not the same machine as where you call the API, replace `localhost` with another IP address.
          default: localhost

paths:

    "/":
        get:
            summary: Get the service status
            operationId: getServiceStatus
            tags:
                - info
            description: |
                Get the service status.
            responses:
                200:
                    $ref: "#/components/responses/serviceStatus"

    "/jobs/":
        get:
            summary: List all jobs
            operationId: listJobs
            tags:
                - info
            description: List all jobs and their statuses.
            responses:
                200:
                    $ref: "#/components/responses/listJobs"
        post:
            summary: Create new job
            operationId: createJob
            tags:
                - process
            parameters:
                - { $ref: "#/components/parameters/workflowName" }
                - { $ref: "#/components/parameters/profileName" }
                - { $ref: "#/components/parameters/jobName" }
            requestBody: { $ref: "#/components/requestBodies/createJob" }
            description: |
                Create a new job for processing using the provided `workflow` and `profile`. To get a full list of available workflows, call the [List available workflows](#list-available-workflows) endpoint.

                After you create a job, use the `addData` API request to add data such as documents, images, and other
                accepted files for processing.

                Delete all created jobs when they are finished using the `deleteJob` request.

                Note that there are two types of options that you can use:
                - **Job options**: Set in the body of the `createJob` API request.
                - **Document options**: Set in the `addData` API request.
            responses:
                201:
                    $ref: "#/components/responses/jobInfo"
                400:
                    $ref: "#/components/responses/badCreateJobRequest"
                415:
                    description: The content type is neither application/json nor application/xml
                503:
                    $ref: "#/components/responses/tooManyJobs"

    "/jobs/{jobId}":
        parameters:
            - { $ref: "#/components/parameters/jobId" }
        get:
            summary: Get job info
            operationId: getJobInfo
            tags:
                - process
            description: |
                Get job info.
            responses:
                200:
                    $ref: "#/components/responses/jobInfo"
                404:
                    $ref: "#/components/responses/jobNotFound"
        delete:
            summary: Delete job
            operationId: deleteJob
            tags:
                - process
            description: |
                When the job processing is completed, delete the job and all associated resources using `deleteJob` API request.
                If you delete the job, you can create new jobs. Jobs that you don't delete explicitly are automatically
                deleted after a timeout or when the service is shut down.

                You can delete a job regardless of its status.
                Jobs with a `processing` status are canceled automatically before deletion.
            responses:
                202:
                    description: "The job will be deleted as soon as processing has finished."
                204:
                    description: "The job has been deleted successfully"
                404:
                    $ref: "#/components/responses/jobNotFound"

    "/jobs/{jobId}/data/":
        parameters:
            - { $ref: "#/components/parameters/jobId" }
        post:
            summary: Add data to job
            operationId: addData
            tags:
                - process
            # Bug in openapi generator: using a $ref with multipart does not seem to work
            # Once it works, use
            # requestBody: { $ref: "#/components/requestBodies/addData" }
            parameters:
                - { $ref: "#/components/parameters/addDataUrl" }
            requestBody:
                required: true
                content:
                    "multipart/form-data":
                        schema: { $ref: "#/components/schemas/addData" }
                    "application/json":
                        schema: { $ref: "#/components/schemas/options" }
                    "application/xml":
                        schema: { $ref: "#/components/schemas/options" }
            description: |
                Add data such as documents, images, and other
                accepted files for processing.

                Use the query parameter `"url"` with
                the `"application/json"` or `"application/xml"` content.

                When you add document options, follow the correct JSON structure.
                Example: Using the `DOC.PASSWORD` option:
                ```json
                [
                  {
                    "name": "DOC.PASSWORD",
                    "value": "Replace with your password as a string."
                  }
                ]
                ```

                After you add all data to the job and send the `addData` request,
                send the `startJob` API request.

            responses:
                201:
                    $ref: "#/components/responses/dataStatus"
                400:
                    $ref: "#/components/responses/badAddDataRequest"
                404:
                    $ref: "#/components/responses/jobNotFound"
                409:
                    $ref: "#/components/responses/jobAlreadyStartedOrCanceled"
                415:
                    description: |
                        - The content type is not multipart/form-data, application/json or application/xml
                        - The content type of the options field in the multipart/form-data content is not application/json

    "/jobs/{jobId}:start":
        parameters:
            - { $ref: "#/components/parameters/jobId" }
        post:
            summary: Start job
            operationId: startJob
            tags:
                - process
            description: |
                Signal that all data was added to a job and the Conversion Service API can start processing it.
                The `startJob` request activates the document merge and post-processing steps.

                After starting a job, send the `getJobResult` API request.
            responses:
                204:
                    description: The job has been started successfully
                404:
                    $ref: "#/components/responses/jobNotFound"
                409:
                    $ref: "#/components/responses/jobAlreadyStartedOrCanceled"

    "/jobs/{jobId}:cancel":
        parameters:
            - { $ref: "#/components/parameters/jobId" }
        post:
            summary: Cancel job
            operationId: cancelJob
            tags:
                - process
            description: |
                Cancel the processing of a job.
                This request has no effect if a job has not been started or has already finished.

                If the job has already finished, its result is not affected by `cancelJob`.
                The job's result can still be requested using `getJobResult`.
                If the job's result is not required anymore, `cancelJob` is optional.
                Instead, the job can simply be deleted using `deleteJob`.
            responses:
                202:
                    description: |
                        Cancellation has been requested successfully.
                        This status is returned even if it is too late to actually cancel the job,
                        for example when the job has already been canceled or finished.
                        The job result returned by `getJobResult` can be used to determine if the job
                        could actually be canceled successfully.
                404:
                    $ref: "#/components/responses/jobNotFound"

    "/jobs/{jobId}/result":
        parameters:
            - { $ref: "#/components/parameters/jobId" }
        get:
            summary: Get job result
            operationId: getJobResult
            tags:
                - process
            description: |
                This request returns the result when it is available and is blocked otherwise. You can also call the `getJobInfo` API request until
                the returned job status is `completed`.

                When the job is completed successfully, retrieve the result data with the `getJobResultData` API request.

                Note that when waiting for the job result, request timeouts can occur after 2 minutes by default.
                You can configure the job and task timeouts in the Conversion Service Configurator under **Workflows & Profiles**. Select a workflow profile and adjust the values in the **Job Settings** section.
                It is recommended to handle request timeouts, especially for long-running jobs or for services under high load.
            responses:
                200: { $ref: "#/components/responses/jobResultInfo" }
                404:
                    $ref: "#/components/responses/jobNotFound"
                409:
                    description: The job has no result, e.g. because it has not yet been started.

    "/jobs/{jobId}/result/{resultId}":
        parameters:
            - { $ref: "#/components/parameters/jobId" }
            - { $ref: "#/components/parameters/resultId" }
        get:
            summary: Get job result data
            operationId: getJobResultData
            tags:
                - process
            description: |
                 Get result data, typically a document, of a job that has completed successfully.
            responses:
                200: { $ref: "#/components/responses/jobResultData" }
                404:
                    $ref: "#/components/responses/jobOrResultNotFound"
                409:
                    description: Unable to get result data, e.g. because it is not yet available. Call `getJobResult` first.

    "/jobs/{jobId}/result/{resultId}:{storeMethod}":
        parameters:
            - { $ref: "#/components/parameters/jobId" }
            - { $ref: "#/components/parameters/resultId" }
            - { $ref: "#/components/parameters/storeMethod" }
            - { $ref: "#/components/parameters/storeResultUrl" }
        post:
            summary: Store job result data
            operationId: storeJobResultData
            tags:
                - process
            description: |
                 Store the result data by sending it to a web server via HTTP(S) request.
            responses:
                204:
                    description: The result has been stored successfully.
                400:
                    $ref: "#/components/responses/badStoreResultRequest"
                404:
                    $ref: "#/components/responses/jobOrResultNotFound"
                409:
                    description: Unable to get result data, e.g. because it is not yet available. Call `getJobResult` first.

    "/workflows":
        get:
            summary: List available workflows
            operationId: listWorkflows
            tags:
                - info
            description: |
                List available workflows.
            responses:
                200:
                    $ref: "#/components/responses/workflowList"

tags:

    - name: process
      description: Job Processing
    - name: info
      description: Service Information

components:

    parameters:

        "workflowName":
            description: |
                The name of the workflow.

                If no workflow is specified, the default workflow of the service is used.
            name: workflow
            in: query
            required: false
            schema: { type: string }
            example: Archive PDF/A-2

        "profileName":
            description: |
                The name of the profile.

                If no profile is specified, the default profile of the workflow is used.
            name: profile
            in: query
            required: false
            schema: { type: string }
            example: default

        "jobName":
            description: |
                The name of the job.

                This value may be used by the workflow,
                e.g. to name the output file when merging multiple inputs.
            name: name
            in: query
            required: false
            schema: { type: string }

        "addDataUrl":
            description: |
                The HTTP(S) URL where the file can be downloaded.

                If this parameter is used, the Content-Type
                must be application/json or application/xml and contain only the options.
            name: url
            in: query
            required: false
            schema: { type: string }

        "jobId":
            description: The job ID as returned by `createJob`.
            name: jobId
            in: path
            required: true
            schema: { type: string }

        "resultId":
            description: The result data's ID as returned by `getJobResult`.
            name: resultId
            in: path
            required: true
            schema: { type: string }

        "storeMethod":
            description: The HTTP method used to store the result.
            name: storeMethod
            in: path
            required: true
            schema: 
                type: string
                enum:
                - "put"
                - "post"

        "storeResultUrl":
            description: The HTTP(S) URL where the file can be stored.
            name: url
            in: query
            required: true
            schema: { type: string }

    requestBodies:

        "createJob":
            description: |
                Body of the `createJob` request. Note that there are two types of options that you can use:
                - **Job options**: Set in the body of the `createJob` API request.
                - **Document options**: Set in the `addData` API request.

            content:
                "application/json":
                    schema: { $ref: "#/components/schemas/options" }
                "application/xml":
                    schema: { $ref: "#/components/schemas/options" }

        "addData":
            description: Body of the addData request
            content:
                "multipart/form-data":
                    schema: { $ref: "#/components/schemas/addData" }

    responses:

        "serviceStatus":
            description: Successful response to the getServiceStatus request
            content:
                "application/json":
                    schema: { $ref: "#/components/schemas/serviceStatus" }
                "application/xml":
                    schema: { $ref: "#/components/schemas/serviceStatus" }

        "listJobs":
            description: Successful response to the listJobs request
            content:
                "application/json":
                    schema: { $ref: "#/components/schemas/jobs" }
                "application/xml":
                    schema: { $ref: "#/components/schemas/jobs" }

        "jobInfo":
            description: Successful response to the createJob and getJobInfo requests
            content:
                "application/json":
                    schema: { $ref: "#/components/schemas/jobInfo" }
                "application/xml":
                    schema: { $ref: "#/components/schemas/jobInfo" }

        "dataStatus":
            description: Successful response to the addData request
            content:
                "application/json":
                    schema: { $ref: "#/components/schemas/dataInfo" }
                "application/xml":
                    schema: { $ref: "#/components/schemas/dataInfo" }

        "jobResultInfo":
            description: Successful response to the getJobResult request
            content:
                "application/json":
                    schema: { $ref: "#/components/schemas/jobResultInfo" }
                "application/xml":
                    schema: { $ref: "#/components/schemas/jobResultInfo" }

        "jobResultData":
            description: Successful response to the getJobResultData request
            content:
                "*/*":
                    schema: {  type: string, format: binary }

        "badCreateJobRequest":
            description: |
                - Request could not be parsed
                - The options are not valid JSON
                - The requested workflow or profile does not exist
            content:
                "application/problem+json":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                "application/problem+xml":
                    schema: { $ref: "#/components/schemas/problemDetails" }

        "badAddDataRequest":
            description: |
                - Request could not be parsed
                - The data is missing
                - The data's filename is missing
                - The options are not valid JSON/XML
                - The file could not be downloaded from the provided URL.
            content:
                "application/problem+json":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                "application/problem+xml":
                    schema: { $ref: "#/components/schemas/problemDetails" }

        "badStoreResultRequest":
            description: |
                - The provided HTTP method is not valid.
                - The query parameter "url" is missing.
                - The provided URL is invalid (not a "http(s):" URL).
                - The file could not be sent to the provided URL.
            content:
                "application/problem+json":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                "application/problem+xml":
                    schema: { $ref: "#/components/schemas/problemDetails" }

        "tooManyJobs":
            description: Too many jobs.
            content:
                "application/problem+json":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                "application/problem+xml":
                    schema: { $ref: "#/components/schemas/problemDetails" }

        "jobNotFound":
            description: The job with the specified ID could not be found.
            content:
                "application/problem+json":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                    examples:
                        jobNotFoundJson: { $ref: "#/components/examples/jobNotFoundJson" }
                "application/problem+xml":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                    examples:
                        jobNotFoundJson: { $ref: "#/components/examples/jobNotFoundXml" }

        "jobOrResultNotFound":
            description: The job or result with the specified ID could not be found.
            content:
                "application/problem+json":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                    examples:
                        jobNotFoundJson: { $ref: "#/components/examples/jobNotFoundJson" }
                "application/problem+xml":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                    examples:
                        jobNotFoundJson: { $ref: "#/components/examples/jobNotFoundXml" }

        "jobAlreadyStartedOrCanceled":
            description: The job has already been started or canceled.
            content:
                "application/problem+json":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                "application/problem+xml":
                    schema: { $ref: "#/components/schemas/problemDetails" }

        "jobAlreadyFinished":
            description: The job has already finished.
            content:
                "application/problem+json":
                    schema: { $ref: "#/components/schemas/problemDetails" }
                "application/problem+xml":
                    schema: { $ref: "#/components/schemas/problemDetails" }

        "workflowList":
            description: A list of all available workflows.
            content:
                "application/json":
                    schema: { $ref: "#/components/schemas/workflows" }
                "application/xml":
                    schema: { $ref: "#/components/schemas/workflows" }

    schemas:

        # multipart/form-data

        "addData":
            type: "object"
            properties:
                "options": { $ref: "#/components/schemas/options" }
                "data":
                    type: string
                    format: binary
                    description: |
                        The file/data to be appended to the job.

                        The `Content-Disposition` header must contain either the
                        `filename` or the `filename*` parameter.
                        It is recommended to set a filename with an extension.
                        Alternatively the MIME type of the data is used to determine its type.

                        The query parameter "url" is ignored if multipart/form-data content is used.
            required:
                - "data"

        # JSON / XML

        "jobId":
            type: string
            description: |
                Unique ID of the job.

                The job ID can be used to control the job, e.g. start it, as well as 
                identify corresponding messages in the service log file. Therefore it is
                highly recommended to log the job ID in the client log file.

        "dataId":
            type: string
            description: |
                Unique ID of the data.

                This ID is returned by `addData` and can be used to associate events and messages
                to specific input data. Therefore it is highly recommended to log the data ID in the
                client log file.

        "resultId":
            type: string
            description: Unique ID that can be used to retrieve the result data using `getJobResultData`.

        "serviceStatusCode":
            type: string
            enum:
                - "running"
                - "warning"
                - "error"

        "isolationStatus":
            type: object
            properties:
                "processCount": { type: integer, description: "Number of isolated worker processes." }
                "queueLength": { type: integer, description: "Number of pending tasks waiting for a free worker process." }
            required:
                - "processCount"
                - "queueLength"

        "jobCounts":
            type: object
            properties:
                "creating": { type: integer, description: "Number of jobs that have not been started yet." }
                "processing": { type: integer, description: "Number of jobs being processed or waiting in a tasks queue." }
                "completed": { type: integer, description: "Number of completed jobs." }
                "total": { type: integer, description: "Total number of active jobs." }
            required:
                - "creating"
                - "processing"
                - "completed"
                - "total"

        "serviceStatus":
            type: object
            properties:
                "version": { type: string, description: "Version of the Conversion Service. Example: \"1.11.0.7\"" }
                "status": { $ref: "#/components/schemas/serviceStatusCode" }
                "startTime": { type: string, format: date-time, description: "The date and time when the service was started."}
                "isolation": { $ref: "#/components/schemas/isolationStatus" }
                "jobCounts": { $ref: "#/components/schemas/jobCounts" }
            required:
                - "version"
                - "status"
                - "isolation"
                - "jobCounts"

        "jobs":
            type: array
            items: { $ref: "#/components/schemas/jobInfo" }
            xml:
                wrapped: true

        "options":
            type: array
            description: |
                List of processing options

                Options can either be set as job options in `createJob` or data specific options in `addData`. Data specific
                options are used to process the respective data and override job options of the same name. It is recommended to
                use job options whenever possible.

                Unless documented otherwise, each option must be set only once.
            items: { $ref: "#/components/schemas/option" }
            xml:
                wrapped: true

        "option":
            type: object
            properties:
                "name": 
                    type: string
                    description: |
                        Option name

                        The list of supported options depends on the `profile` used. Common names are:

                        - `DOC.PASSWORD`: Password used for password protected files. This option can be added multiple times,
                            where all passwords are tried. The list of passwords is also used to open embedded and/or attached files.
                "value":
                    type: string
                    description: |
                        The option's value.

                        Note that the value must match the type required by the option. Otherwise workflow processing will abort with
                        an error code `option`.
            required:
                - "name"
                - "value"
            xml:
                name: "option"

        "jobInfo":
            type: object
            properties:
                "jobId": { $ref: "#/components/schemas/jobId" }
                "status": { $ref: "#/components/schemas/jobStatus" }
            required:
                - "jobId"
                - "status"
            xml:
                name: "job"

        "jobStatus":
            type: object
            properties:
                "code": { $ref: "#/components/schemas/jobStatusCode" }
                "message": { type: string, description: "A message describing the job's status in more detail. Example: \"Converting 'input.pdf' to PDF/A.\"" }
            required:
                - "code"
                - "message"

        "jobStatusCode":
            type: string
            enum:
                - "creating"
                - "pending"
                - "processing"
                - "completed"

        "dataInfo":
            type: object
            properties:
                "dataId": { $ref: "#/components/schemas/dataId" }
            required:
                - "dataId"
            xml:
                name: "data"

        "eventCode":
            type: string
            enum:
                - "ExternalResourceUnavailable"
                - "ContentClipped"
                - "ContentOverflow"
                - "ContentRasterized"
                - "PageRenderer"
                - "VisualDifferences"
                - "Colorants"
                - "LayersRemoved"
                - "TransparencyRemoved"
                - "MetadataRemoved"
                - "CorruptionRepaired"
                - "SignatureRemoved"
                - "ContentRecovered"
                - "FontSubstituted"
                - "AnnotationRemoved"
                - "MultimediaRemoved"
                - "ActionRemoved"
                - "StructureRemoved"
                - "PartialExtraction"
                - "NotLinearized"
                - "OcrIncomplete"
                - "UnicodesIncomplete"
                - "TaggingIncomplete"
                - "Event"
                - "ChildRemoved"

        "severity":
            type: string
            enum:
                - "info"
                - "warning"
                - "error"

        "event":
            type: object
            properties:
                "code": { $ref: "#/components/schemas/eventCode" }
                "severity": { $ref: "#/components/schemas/severity" }
                "dataId": { $ref: "#/components/schemas/dataId" }
                "dataPart": { type: string, description: "The part of the data that is affected, e.g. an embedded file or attachment." }
                "message": { type: string }
            required:
                - "code"
                - "severity"
                - "message"
            xml:
                name: "event"

        "events":
            type: array
            description: |
                List of processing events.

                Depending on the severity, different actions are recommended:

                - `info`: Event is of a strictly informational nature and can be ignored. If a verbose processing log is written,
                    such events can be included.
                - `warning`: This event is a critical conversion warning that should be handled. 
                - `error`: Such an event occurs only in failed jobs and contains error information additional to the job result info's
                    error property.

            items: { $ref: "#/components/schemas/event" }
            xml:
                wrapped: true

        "resultDataInfoList":
            type: array
            items: { $ref: "#/components/schemas/resultDataInfo" }
            xml:
                wrapped: true

        "properties":
            type: array
            items: { $ref: "#/components/schemas/property" }

        "property":
            type: object
            description: |
                Additional properties of the data.

                The list of additional properties depends on the workflow used. For more information see the user manual.
            properties:
                "name": { type: string, description: "Name of the property" }
                "value": { type: string, description: "Value of the property" }
            required:
                - "name"
                - "value"

        "resultDataInfo":
            type: object
            properties:
                "fileName": { type: string }
                "size": { type: integer }
                "resultId": { $ref: "#/components/schemas/resultId" }
                "properties": { $ref: "#/components/schemas/properties" }
            required:
                - "fileName"
                - "size"
                - "resultId"
                - "properties"
            xml:
                name: "data"

        "errorCode":
            type: string
            enum:
                - "internal"
                - "external"
                - "configuration"
                - "generic"
                - "unsupportedFormat"
                - "unsupportedFeature"
                - "option"
                - "canceled"
                - "timeout"
                - "password"
                - "conformance"
                - "corrupt"

        "error":
            type: object
            properties:
                "code": { $ref: "#/components/schemas/errorCode" }
                "message": { type: string }
            required:
                - "code"
                - "message"

        "jobResultInfo":
            type: object
            properties:
                "status":
                    type: string
                    enum: 
                        - "success"
                        - "warning"
                        - "error"
                    description: |
                        Whether the job has been processed successfully.

                        Successful jobs typically have `dataList`, otherwise the property `error` contains a description of the error.
                        
                "error": { $ref: "#/components/schemas/error" }
                "events": { $ref: "#/components/schemas/events" }
                "dataList": { $ref: "#/components/schemas/resultDataInfoList" }
            required:
                - "status"
            xml:
                name: "result"

        "workflows":
            type: array
            items: { $ref: "#/components/schemas/workflowInfo" }
            xml:
                wrapped: true

        "workflowInfo":
            type: object
            properties:
                "name": { type: string }
                "isDefault": { type: boolean }
                "profiles":
                    type: array
                    items: { $ref: "#/components/schemas/profileInfo" }
                    xml:
                        wrapped: true
            xml:
                name: "workflow"

        "profileInfo":
            type: object
            properties:
                "name": { type: string }
                "isDefault": { type: boolean }
            xml:
                name: "profile"

        "problemDetails":
            type: object
            description: Problem details (RFC 7807).
            properties:
                "type": { type: string, description: "A URI reference that identifies the problem type. Note that this URI cannot be dereferenced." }
                "title": { type: string, description: "A short, human-readable summary of the problem type." }
                "status": { type: integer, description: "The HTTP status code." }
                "detail": { type: string, description: "A human-readable explanation specific to this occurrence of the problem." }
            required:
                - "type"
                - "title"
                - "detail"
                - "status"
            xml:
                name: "problem"
                namespace: "urn:ietf:rfc:7807"

    examples:

        "jobNotFoundJson":
            value: |
                {
                    "type": "http://www.pdf-tools.com/service/rest/errors/jobNotFound",
                    "title": "Job not found.",
                    "detail": "The job with ID 'job_XYZ' could not be found.",
                    "status": 404
                }

        "jobNotFoundXml":
            value: |
                <problem xmlns="urn:ietf:rfc:7807">
                  <type>http://www.pdf-tools.com/service/rest/errors/jobNotFound</type>
                  <title>Job not found.</title>
                  <detail>The job with ID 'job_XYZ' could not be found.</detail>
                  <status>404</status>
                </problem>

