openapi: 3.1.0

info:
  title: Blazelock API
  description: Add real-time malware detection to your application with just a few lines of code.
  version: 1.0.1
  contact:
    name: Blazelock Team
    url: https://blazelock.com

externalDocs:
  description: Read the full API documentation
  url: https://docs.blazelock.com/en/api-reference/introduction

servers:
  - url: https://api.blazelock.com/v1

security:
  - bearerAuth: []

tags:
  - name: File Scans
    description: Scan files for malware through the Blazelock API.

paths:
  /file-scans:
    post:
      operationId: submit-async-file-scan
      summary: Submit an asynchronous file scan
      description: |
        Upload a file for malware scanning.
        The scan continues asynchronously in the background. The response returns the
        initial processing state together with the created scan ID.

        Use the scan ID to poll for the result through the GET endpoints.

        If webhooks are enabled in the Blazelock Dashboard, webhook events are sent as
        the scan progresses.
      tags:
        - File Scans
      parameters:
        - $ref: '#/components/parameters/ContentLanguageHeader'
      requestBody:
        $ref: '#/components/requestBodies/AsyncFileScanRequest'
      responses:
        '201':
          description: File scan accepted and queued for processing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileScanProcessing'
              examples:
                processing:
                  $ref: '#/components/examples/FileScanProcessingAsyncExample'
        '409':
          $ref: '#/components/responses/DuplicateExternalReferenceIdResponse'

  /file-scans/sync:
    post:
      operationId: submit-sync-file-scan
      summary: Submit a synchronous file scan
      description: |
        Upload a file for malware scanning and wait for a terminal result within the
        synchronous polling window of 90 seconds.

        Depending on the outcome, the response returns a completed or failed state.

        If the polling window is reached before a terminal result is available, a
        timeout error is returned together with the created scan ID. Use the scan ID
        to continue polling through the GET endpoints.

        If webhooks are enabled in the Blazelock Dashboard, webhook events are sent as
        the scan progresses.
      tags:
        - File Scans
      parameters:
        - $ref: '#/components/parameters/ContentLanguageHeader'
      requestBody:
        $ref: '#/components/requestBodies/SyncFileScanRequest'
      responses:
        '201':
          description: Terminal file scan result returned within the synchronous polling window.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/FileScanCompleted'
                  - $ref: '#/components/schemas/FileScanFailed'
                discriminator:
                  propertyName: status
                  mapping:
                    completed: '#/components/schemas/FileScanCompleted'
                    failed: '#/components/schemas/FileScanFailed'
              examples:
                completed_clean:
                  $ref: '#/components/examples/FileScanCompletedCleanSyncExample'
                completed_infected:
                  $ref: '#/components/examples/FileScanCompletedInfectedSyncExample'
                completed_warning:
                  $ref: '#/components/examples/FileScanCompletedWarningSyncExample'
                failed:
                  $ref: '#/components/examples/FileScanFailedSyncExample'
        '408':
          $ref: '#/components/responses/SyncScanTimeoutResponse'
        '409':
          $ref: '#/components/responses/DuplicateExternalReferenceIdResponse'

  /file-scans/{id}:
    get:
      operationId: get-file-scan
      summary: Get a file scan
      description: |
        Retrieve the current state of a file scan by its Blazelock scan ID.

        Depending on the scan progress and outcome, the response returns a processing,
        completed, or failed state.
      tags:
        - File Scans
      parameters:
        - $ref: '#/components/parameters/ContentLanguageHeader'
        - $ref: '#/components/parameters/FileScanIdPathParameter'
      responses:
        '200':
          description: Current file scan state.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/FileScanProcessing'
                  - $ref: '#/components/schemas/FileScanCompleted'
                  - $ref: '#/components/schemas/FileScanFailed'
                discriminator:
                  propertyName: status
                  mapping:
                    processing: '#/components/schemas/FileScanProcessing'
                    completed: '#/components/schemas/FileScanCompleted'
                    failed: '#/components/schemas/FileScanFailed'
              examples:
                processing:
                  $ref: '#/components/examples/FileScanProcessingAsyncExample'
                completed_clean:
                  $ref: '#/components/examples/FileScanCompletedCleanAsyncExample'
                completed_infected:
                  $ref: '#/components/examples/FileScanCompletedInfectedAsyncExample'
                completed_warning:
                  $ref: '#/components/examples/FileScanCompletedWarningAsyncExample'
                failed:
                  $ref: '#/components/examples/FileScanFailedAsyncExample'

  /file-scans/external-reference/{external_reference_id}:
    get:
      operationId: get-file-scan-by-external-reference-id
      summary: Get a file scan by external reference ID
      description: |
        Retrieve a file scan by the client-provided external reference ID instead of
        the Blazelock scan ID.

        The external reference ID is resolved within the authenticated API integration.

        Depending on the scan progress and outcome, the response returns a processing,
        completed, or failed state.
      tags:
        - File Scans
      parameters:
        - $ref: '#/components/parameters/ContentLanguageHeader'
        - $ref: '#/components/parameters/ExternalReferenceIdPathParameter'
      responses:
        '200':
          description: Current file scan state resolved by external reference ID.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/FileScanProcessing'
                  - $ref: '#/components/schemas/FileScanCompleted'
                  - $ref: '#/components/schemas/FileScanFailed'
                discriminator:
                  propertyName: status
                  mapping:
                    processing: '#/components/schemas/FileScanProcessing'
                    completed: '#/components/schemas/FileScanCompleted'
                    failed: '#/components/schemas/FileScanFailed'
              examples:
                processing:
                  $ref: '#/components/examples/FileScanProcessingAsyncExample'
                completed_clean:
                  $ref: '#/components/examples/FileScanCompletedCleanAsyncExample'
                completed_infected:
                  $ref: '#/components/examples/FileScanCompletedInfectedAsyncExample'
                completed_warning:
                  $ref: '#/components/examples/FileScanCompletedWarningAsyncExample'
                failed:
                  $ref: '#/components/examples/FileScanFailedAsyncExample'

webhooks:
  file_scan.submitted:
    post:
      operationId: file-scan-submitted
      summary: File scan submitted
      description: |
        Triggered when a new file scan has been submitted through the API.

        We recommend verifying the request signature before processing the event. See
        [Webhook signature validation](https://docs.blazelock.com/en/api-reference/webhook-validation)
        for details.
      tags:
        - File Scans
      security: []
      parameters:
        - $ref: '#/components/parameters/WebhookTimestampHeader'
        - $ref: '#/components/parameters/WebhookSignatureHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FileScanSubmittedWebhook'
            examples:
              file_scan_submitted:
                $ref: '#/components/examples/FileScanSubmittedWebhookExample'
      responses:
        2XX:
          $ref: '#/components/responses/WebhookResponse'

  file_scan.completed:
    post:
      operationId: file-scan-completed
      summary: File scan completed
      description: |
        Triggered when a file scan submitted through the API has completed successfully and the
        results are available.

        We recommend verifying the request signature before processing the event. See
        [Webhook signature validation](https://docs.blazelock.com/en/api-reference/webhook-validation)
        for details.
      tags:
        - File Scans
      security: []
      parameters:
        - $ref: '#/components/parameters/WebhookTimestampHeader'
        - $ref: '#/components/parameters/WebhookSignatureHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FileScanCompletedWebhook'
            examples:
              completed_clean:
                $ref: '#/components/examples/FileScanCompletedWebhookExample'
              completed_infected:
                $ref: '#/components/examples/FileScanCompletedInfectedWebhookExample'
              completed_warning:
                $ref: '#/components/examples/FileScanCompletedWarningWebhookExample'
      responses:
        2XX:
          $ref: '#/components/responses/WebhookResponse'

  file_scan.failed:
    post:
      operationId: file-scan-failed
      summary: File scan failed
      description: |
        Triggered when a file scan submitted through the API could not be completed due to an
        error.

        We recommend verifying the request signature before processing the event. See
        [Webhook signature validation](https://docs.blazelock.com/en/api-reference/webhook-validation)
        for details.
      tags:
        - File Scans
      security: []
      parameters:
        - $ref: '#/components/parameters/WebhookTimestampHeader'
        - $ref: '#/components/parameters/WebhookSignatureHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FileScanFailedWebhook'
            examples:
              file_scan_failed:
                $ref: '#/components/examples/FileScanFailedWebhookExample'
      responses:
        2XX:
          $ref: '#/components/responses/WebhookResponse'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API_KEY
      description: |
        API key generated in the Blazelock Dashboard.

        Send it in the HTTP `Authorization` header as `Bearer <api-key>`.

  parameters:
    ContentLanguageHeader:
      name: Content-Language
      in: header
      required: false
      description: >
        Two-letter ISO language code used for localized human-readable response messages.
        Supported values:
         * `en` = English
         * `de` = German
      schema:
        type: string
        enum:
          - en
          - de
        examples:
          - en

    WebhookTimestampHeader:
      name: X-Blazelock-Webhook-Timestamp
      in: header
      required: true
      description: >
        Unix timestamp indicating when the webhook was sent. This value is updated on each
        delivery attempt, including retries. As a best practice, you should verify that the
        timestamp is no more than 5 minutes in the past to prevent replay attacks.
      schema:
        type: integer
        format: int64
        examples:
          - 1741520644

    WebhookSignatureHeader:
      name: X-Blazelock-Webhook-Signature
      in: header
      required: true
      description: >
        SHA256 signature used to verify the authenticity of the webhook payload. The signature
        is computed over the string `{timestamp}.{body}`, where `timestamp` is the value of the
        `X-Blazelock-Webhook-Timestamp` header and `body` is the raw JSON request body. The
        signature is generated using the webhook secret, which can be found in the Blazelock
        dashboard under the API integration settings.
      schema:
        type: string
        examples:
          - a3b9f1c8d4e7f2a1b5c3d9e6f8a2b4c7d1e5f3a8b6c4d2e9f7a1b3c5d8e6f4a2

    FileScanIdPathParameter:
      name: id
      in: path
      required: true
      description: ID of the file scan.
      schema:
        $ref: '#/components/schemas/FileScanId'

    ExternalReferenceIdPathParameter:
      name: external_reference_id
      in: path
      required: true
      description: Client-provided external reference ID resolved within the authenticated API integration.
      schema:
        allOf:
          - $ref: '#/components/schemas/FileScanExternalReferenceId'
          - type: string

  requestBodies:
    AsyncFileScanRequest:
      required: true
      description: >
        Multipart form payload for an asynchronous file scan. It contains a binary `file`
        part and an `attributes` part encoded as JSON with the content type
        `application/json`.
      content:
        multipart/form-data:
          schema:
            $ref: '#/components/schemas/AsyncFileScanRequest'
          encoding:
            attributes:
              contentType: application/json

    SyncFileScanRequest:
      required: true
      description: >
        Multipart form payload for a synchronous file scan. It contains a binary `file`
        part and an `attributes` part encoded as JSON with the content type
        `application/json`.
      content:
        multipart/form-data:
          schema:
            $ref: '#/components/schemas/SyncFileScanRequest'
          encoding:
            attributes:
              contentType: application/json

  schemas:
    AsyncFileScanRequest:
      type: object
      description: Request payload for submitting an asynchronous file scan.
      properties:
        attributes:
          $ref: '#/components/schemas/FileScanRequestAttributes'
        file:
          $ref: '#/components/schemas/AsyncFileUpload'
      required:
        - attributes
        - file

    SyncFileScanRequest:
      type: object
      description: Request payload for submitting a synchronous file scan.
      properties:
        attributes:
          $ref: '#/components/schemas/FileScanRequestAttributes'
        file:
          $ref: '#/components/schemas/SyncFileUpload'
      required:
        - attributes
        - file

    FileScanRequestAttributes:
      type: object
      description: Metadata submitted together with the file upload.
      properties:
        file_name:
          $ref: '#/components/schemas/FileScanFileName'
        external_reference_id:
          $ref: '#/components/schemas/FileScanExternalReferenceId'
      required:
        - file_name

    AsyncFileUpload:
      type: string
      format: binary
      maxLength: 104857600
      description: Binary file content to scan. Maximum file size is 100 MB.

    SyncFileUpload:
      type: string
      format: binary
      maxLength: 10485760
      description: Binary file content to scan. Maximum file size is 10 MB.

    FileScanProcessing:
      type: object
      description: Response payload for a file scan that is still being processed.
      properties:
        id:
          $ref: '#/components/schemas/FileScanId'
        external_reference_id:
          $ref: '#/components/schemas/FileScanExternalReferenceId'
        status:
          $ref: '#/components/schemas/FileScanStatusProcessing'
        execution_mode:
          $ref: '#/components/schemas/FileScanExecutionMode'
        file_name:
          $ref: '#/components/schemas/FileScanFileName'
        file_size:
          $ref: '#/components/schemas/FileScanFileSize'
        submitted_at:
          $ref: '#/components/schemas/FileScanSubmittedAt'
      required:
        - id
        - external_reference_id
        - status
        - execution_mode
        - file_name
        - file_size
        - submitted_at

    FileScanCompleted:
      type: object
      description: Response payload for a file scan that completed successfully.
      properties:
        id:
          $ref: '#/components/schemas/FileScanId'
        external_reference_id:
          $ref: '#/components/schemas/FileScanExternalReferenceId'
        status:
          $ref: '#/components/schemas/FileScanStatusCompleted'
        execution_mode:
          $ref: '#/components/schemas/FileScanExecutionMode'
        file_name:
          $ref: '#/components/schemas/FileScanFileName'
        file_size:
          $ref: '#/components/schemas/FileScanFileSize'
        file_type:
          $ref: '#/components/schemas/FileScanFileType'
        file_hash:
          $ref: '#/components/schemas/FileHash'
        result:
          $ref: '#/components/schemas/ScanResult'
        completed_at:
          $ref: '#/components/schemas/FileScanCompletedAt'
        scan_duration_ms:
          $ref: '#/components/schemas/FileScanDurationMs'
        submitted_at:
          $ref: '#/components/schemas/FileScanSubmittedAt'
      required:
        - id
        - external_reference_id
        - status
        - execution_mode
        - file_name
        - file_size
        - file_type
        - file_hash
        - result
        - completed_at
        - scan_duration_ms
        - submitted_at

    FileScanFailed:
      type: object
      description: Response payload for a file scan that failed.
      properties:
        id:
          $ref: '#/components/schemas/FileScanId'
        external_reference_id:
          $ref: '#/components/schemas/FileScanExternalReferenceId'
        status:
          $ref: '#/components/schemas/FileScanStatusFailed'
        execution_mode:
          $ref: '#/components/schemas/FileScanExecutionMode'
        file_name:
          $ref: '#/components/schemas/FileScanFileName'
        file_size:
          $ref: '#/components/schemas/FileScanFileSize'
        error_code:
          $ref: '#/components/schemas/FileScanErrorCode'
        submitted_at:
          $ref: '#/components/schemas/FileScanSubmittedAt'
      required:
        - id
        - external_reference_id
        - status
        - execution_mode
        - file_name
        - file_size
        - error_code
        - submitted_at

    WebhookEnvelope:
      type: object
      description: Shared envelope for all outbound webhook payloads.
      properties:
        event:
          type: string
          description: The event key that triggered this webhook.
        integration_id:
          $ref: '#/components/schemas/IntegrationId'
        occurred_at:
          $ref: '#/components/schemas/WebhookOccurredAt'
        data:
          type: object
          description: Event-specific payload. Its shape depends on the `event` value.
      required:
        - event
        - integration_id
        - occurred_at
        - data

    FileScanSubmittedWebhook:
      description: Outbound webhook payload for the `file_scan.submitted` event.
      allOf:
        - $ref: '#/components/schemas/WebhookEnvelope'
        - type: object
          properties:
            event:
              $ref: '#/components/schemas/WebhookEventFileScanSubmitted'
            data:
              $ref: '#/components/schemas/FileScanProcessing'

    FileScanCompletedWebhook:
      description: Outbound webhook payload for the `file_scan.completed` event.
      allOf:
        - $ref: '#/components/schemas/WebhookEnvelope'
        - type: object
          properties:
            event:
              $ref: '#/components/schemas/WebhookEventFileScanCompleted'
            data:
              $ref: '#/components/schemas/FileScanCompleted'

    FileScanFailedWebhook:
      description: Outbound webhook payload for the `file_scan.failed` event.
      allOf:
        - $ref: '#/components/schemas/WebhookEnvelope'
        - type: object
          properties:
            event:
              $ref: '#/components/schemas/WebhookEventFileScanFailed'
            data:
              $ref: '#/components/schemas/FileScanFailed'

    WebhookEventFileScanSubmitted:
      type: string
      enum:
        - file_scan.submitted
      description: Triggered when a new file scan has been submitted through the API.

    WebhookEventFileScanCompleted:
      type: string
      enum:
        - file_scan.completed
      description: Triggered when a file scan has completed successfully and the results are available.

    WebhookEventFileScanFailed:
      type: string
      enum:
        - file_scan.failed
      description: Triggered when a file scan could not be completed due to an error.

    IntegrationId:
      type: string
      format: uuid
      description: ID of the API integration that created the file scan.
      examples:
        - 019583d8-b217-72e1-91a5-6f6b4e1a1c42

    WebhookOccurredAt:
      type: string
      format: date-time
      description: ISO 8601 timestamp indicating when the event occurred on Blazelock's side.
      examples:
        - 2026-03-09T12:35:12.000Z

    FileScanId:
      type: string
      format: uuid
      description: Unique identifier of the file scan.
      examples:
        - 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1

    FileScanExternalReferenceId:
      type:
        - string
        - 'null'
      maxLength: 255
      pattern: ^[a-zA-Z0-9._:/#@-]+$
      description: >
        Optional external reference ID provided when submitting the scan. Must be at most
        255 characters long and may only contain uppercase and lowercase letters, digits,
        `.`, `_`, `:`, `/`, `#`, `@`, and `-`. Spaces and all other characters are not allowed.
        If provided, the value must be unique within the same API integration.
      examples:
        - invoice-4711

    FileScanStatusProcessing:
      type: string
      enum:
        - processing
      description: File scan is still being processed.

    FileScanStatusCompleted:
      type: string
      enum:
        - completed
      description: File scan completed successfully.

    FileScanStatusFailed:
      type: string
      enum:
        - failed
      description: File scan failed.

    FileScanExecutionMode:
      type: string
      enum:
        - sync
        - async
      description: Whether the scan was requested through the synchronous or asynchronous endpoint.

    FileScanFileName:
      type: string
      maxLength: 255
      description: Client-provided file name associated with the uploaded file. Maximum length is 255 characters.
      examples:
        - invoice.pdf

    FileScanFileSize:
      type: integer
      format: int64
      description: Size of the uploaded file in bytes.
      examples:
        - 245761

    FileScanFileType:
      type: string
      description: Detected MIME type of the scanned file.
      examples:
        - application/pdf

    FileScanSubmittedAt:
      type: string
      format: date-time
      description: ISO 8601 timestamp indicating when the scan was submitted.
      examples:
        - 2026-03-09T12:34:56.000Z

    FileScanCompletedAt:
      type: string
      format: date-time
      description: ISO 8601 timestamp indicating when the scan finished.
      examples:
        - 2026-03-09T12:35:11.000Z

    FileScanDurationMs:
      type: integer
      format: int32
      description: Total scan duration in milliseconds.
      examples:
        - 250

    FileScanErrorCode:
      type: string
      description: >
        Machine-readable error code describing why the scan failed.
         * `upload_failed` - The uploaded file could not be stored.
         * `file_analysis_failed` - File metadata or hashes could not be determined.
         * `test_file_signature_failed` - The file matched a test file signature that intentionally forces a failed scan.
         * `scan_failed` - The malware scan failed for a reason other than a timeout.
         * `scan_timeout` - The malware scan exceeded the allowed processing time.
         * `unknown_error` - The scan failed due to an unexpected internal error.
      enum:
        - upload_failed
        - file_analysis_failed
        - test_file_signature_failed
        - scan_failed
        - scan_timeout
        - unknown_error
      examples:
        - scan_timeout

    FileHash:
      type: object
      description: Cryptographic hashes of the scanned file.
      properties:
        md5:
          $ref: '#/components/schemas/FileHashMd5'
        sha1:
          $ref: '#/components/schemas/FileHashSha1'
        sha256:
          $ref: '#/components/schemas/FileHashSha256'
      required:
        - md5
        - sha1
        - sha256

    FileHashMd5:
      type: string
      description: MD5 hash of the file.
      examples:
        - d41d8cd98f00b204e9800998ecf8427e

    FileHashSha1:
      type: string
      description: SHA-1 hash of the file.
      examples:
        - da39a3ee5e6b4b0d3255bfef95601890afd80709

    FileHashSha256:
      type: string
      description: SHA-256 hash of the file.
      examples:
        - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

    ScanResult:
      type: object
      description: The malware scan result.
      properties:
        safe:
          type: boolean
          description: >
            `true` if Blazelock considers the file safe, `false` otherwise.
            A `warning` result is considered unsafe and returns `false`.
          examples:
            - true
        detailed:
          $ref: '#/components/schemas/FileScanDetailedResult'
        findings:
          type: array
          description: Detected threats or warnings for a completed scan.
          items:
            type: string
      required:
        - safe
        - detailed
        - findings

    FileScanDetailedResult:
      type: string
      enum:
        - clean
        - infected
        - warning
      description: Detailed scan result classification.
      examples:
        - clean

    ApiError:
      type: object
      description: Standard error response returned by the REST API.
      properties:
        code:
          type: string
          description: Stable machine-readable error identifier.
          examples:
            - unauthenticated
        message:
          type: string
          description: Human-readable explanation of the problem.
          examples:
            - You must be authenticated to perform this action.
      required:
        - code
        - message

    SyncScanTimeoutError:
      allOf:
        - $ref: '#/components/schemas/ApiError'
        - type: object
          properties:
            file_scan_id:
              $ref: '#/components/schemas/FileScanId'
          required:
            - file_scan_id

  examples:
    FileScanProcessingAsyncExample:
      summary: Processing
      value:
        id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
        external_reference_id: invoice-4711
        status: processing
        execution_mode: async
        file_name: invoice.pdf
        file_size: 245761
        submitted_at: 2026-03-09T12:34:56.000Z

    FileScanCompletedCleanAsyncExample:
      summary: Completed, clean
      value:
        id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
        external_reference_id: invoice-4711
        status: completed
        execution_mode: async
        file_name: invoice.pdf
        file_size: 245761
        file_type: application/pdf
        file_hash:
          md5: d41d8cd98f00b204e9800998ecf8427e
          sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
          sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
        result:
          safe: true
          detailed: clean
          findings: []
        completed_at: 2026-03-09T12:35:11.000Z
        scan_duration_ms: 250
        submitted_at: 2026-03-09T12:34:56.000Z

    FileScanCompletedInfectedAsyncExample:
      summary: Completed, infected
      value:
        id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
        external_reference_id: invoice-4711
        status: completed
        execution_mode: async
        file_name: malware.exe
        file_size: 5678
        file_type: application/x-msdownload
        file_hash:
          md5: 7b8f4f9a4d6e2c1b3a5f7d9e0c2a4b6d
          sha1: 3f786850e387550fdab836ed7e6dc881de23001b
          sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
        result:
          safe: false
          detailed: infected
          findings:
            - Virus.Script/Obfuscated.Dropper
            - Malware.Win32/Loader.B
        completed_at: 2026-03-09T12:35:11.000Z
        scan_duration_ms: 1200
        submitted_at: 2026-03-09T12:34:56.000Z

    FileScanCompletedWarningAsyncExample:
      summary: Completed, warning
      value:
        id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
        external_reference_id: invoice-4711
        status: completed
        execution_mode: async
        file_name: invoice.xlsm
        file_size: 3456
        file_type: application/vnd.ms-excel.sheet.macroEnabled.12
        file_hash:
          md5: e2fc714c4727ee9395f324cd2e7f331f
          sha1: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
          sha256: b94d27b9934d3e08a52e52d7da7dabfade4f6d3f1f9f5d7e0d7c6f216a73abdb
        result:
          safe: false
          detailed: warning
          findings:
            - This file contains macros that could potentially execute malicious code. Review the macros before enabling them.
        completed_at: 2026-03-09T12:35:11.000Z
        scan_duration_ms: 640
        submitted_at: 2026-03-09T12:34:56.000Z

    FileScanFailedAsyncExample:
      summary: Failed
      value:
        id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
        external_reference_id: invoice-4711
        status: failed
        execution_mode: async
        file_name: invoice.pdf
        file_size: 245761
        error_code: scan_failed
        submitted_at: 2026-03-09T12:34:56.000Z

    FileScanCompletedCleanSyncExample:
      summary: Completed, clean
      value:
        id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
        external_reference_id: invoice-4711
        status: completed
        execution_mode: sync
        file_name: invoice.pdf
        file_size: 245761
        file_type: application/pdf
        file_hash:
          md5: d41d8cd98f00b204e9800998ecf8427e
          sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
          sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
        result:
          safe: true
          detailed: clean
          findings: []
        completed_at: 2026-03-09T12:35:11.000Z
        scan_duration_ms: 250
        submitted_at: 2026-03-09T12:34:56.000Z

    FileScanCompletedInfectedSyncExample:
      summary: Completed, infected
      value:
        id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
        external_reference_id: invoice-4711
        status: completed
        execution_mode: sync
        file_name: malware.exe
        file_size: 5678
        file_type: application/x-msdownload
        file_hash:
          md5: 7b8f4f9a4d6e2c1b3a5f7d9e0c2a4b6d
          sha1: 3f786850e387550fdab836ed7e6dc881de23001b
          sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
        result:
          safe: false
          detailed: infected
          findings:
            - Virus.Script/Obfuscated.Dropper
            - Malware.Win32/Loader.B
        completed_at: 2026-03-09T12:35:11.000Z
        scan_duration_ms: 1200
        submitted_at: 2026-03-09T12:34:56.000Z

    FileScanCompletedWarningSyncExample:
      summary: Completed, warning
      value:
        id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
        external_reference_id: invoice-4711
        status: completed
        execution_mode: sync
        file_name: invoice.xlsm
        file_size: 3456
        file_type: application/vnd.ms-excel.sheet.macroEnabled.12
        file_hash:
          md5: e2fc714c4727ee9395f324cd2e7f331f
          sha1: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
          sha256: b94d27b9934d3e08a52e52d7da7dabfade4f6d3f1f9f5d7e0d7c6f216a73abdb
        result:
          safe: false
          detailed: warning
          findings:
            - This file contains macros that could potentially execute malicious code. Review the macros before enabling them.
        completed_at: 2026-03-09T12:35:11.000Z
        scan_duration_ms: 640
        submitted_at: 2026-03-09T12:34:56.000Z

    FileScanFailedSyncExample:
      summary: Failed
      value:
        id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
        external_reference_id: invoice-4711
        status: failed
        execution_mode: sync
        file_name: invoice.pdf
        file_size: 245761
        error_code: scan_failed
        submitted_at: 2026-03-09T12:34:56.000Z

    FileScanSubmittedWebhookExample:
      summary: File scan submitted
      value:
        event: file_scan.submitted
        integration_id: 019583d8-b217-72e1-91a5-6f6b4e1a1c42
        occurred_at: 2026-03-09T12:35:12.000Z
        data:
          id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
          external_reference_id: invoice-4711
          status: processing
          execution_mode: async
          file_name: invoice.pdf
          file_size: 245761
          submitted_at: 2026-03-09T12:34:56.000Z

    FileScanCompletedWebhookExample:
      summary: File scan completed
      value:
        event: file_scan.completed
        integration_id: 019583d8-b217-72e1-91a5-6f6b4e1a1c42
        occurred_at: 2026-03-09T12:35:12.000Z
        data:
          id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
          external_reference_id: invoice-4711
          status: completed
          execution_mode: async
          file_name: invoice.pdf
          file_size: 245761
          file_type: application/pdf
          file_hash:
            md5: d41d8cd98f00b204e9800998ecf8427e
            sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
            sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
          result:
            safe: true
            detailed: clean
            findings: []
          completed_at: 2026-03-09T12:35:11.000Z
          scan_duration_ms: 250
          submitted_at: 2026-03-09T12:34:56.000Z

    FileScanCompletedInfectedWebhookExample:
      summary: File scan completed, infected
      value:
        event: file_scan.completed
        integration_id: 019583d8-b217-72e1-91a5-6f6b4e1a1c42
        occurred_at: 2026-03-09T12:35:12.000Z
        data:
          id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
          external_reference_id: invoice-4711
          status: completed
          execution_mode: async
          file_name: malware.exe
          file_size: 5678
          file_type: application/x-msdownload
          file_hash:
            md5: 7b8f4f9a4d6e2c1b3a5f7d9e0c2a4b6d
            sha1: 3f786850e387550fdab836ed7e6dc881de23001b
            sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
          result:
            safe: false
            detailed: infected
            findings:
              - Virus.Script/Obfuscated.Dropper
              - Malware.Win32/Loader.B
          completed_at: 2026-03-09T12:35:11.000Z
          scan_duration_ms: 1200
          submitted_at: 2026-03-09T12:34:56.000Z

    FileScanCompletedWarningWebhookExample:
      summary: File scan completed, warning
      value:
        event: file_scan.completed
        integration_id: 019583d8-b217-72e1-91a5-6f6b4e1a1c42
        occurred_at: 2026-03-09T12:35:12.000Z
        data:
          id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
          external_reference_id: invoice-4711
          status: completed
          execution_mode: async
          file_name: invoice.xlsm
          file_size: 3456
          file_type: application/vnd.ms-excel.sheet.macroEnabled.12
          file_hash:
            md5: e2fc714c4727ee9395f324cd2e7f331f
            sha1: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
            sha256: b94d27b9934d3e08a52e52d7da7dabfade4f6d3f1f9f5d7e0d7c6f216a73abdb
          result:
            safe: false
            detailed: warning
            findings:
              - This file contains macros that could potentially execute malicious code. Review the macros before enabling them.
          completed_at: 2026-03-09T12:35:11.000Z
          scan_duration_ms: 640
          submitted_at: 2026-03-09T12:34:56.000Z

    FileScanFailedWebhookExample:
      summary: File scan failed
      value:
        event: file_scan.failed
        integration_id: 019583d8-b217-72e1-91a5-6f6b4e1a1c42
        occurred_at: 2026-03-09T12:35:12.000Z
        data:
          id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
          external_reference_id: invoice-4711
          status: failed
          execution_mode: async
          file_name: invoice.pdf
          file_size: 245761
          error_code: scan_failed
          submitted_at: 2026-03-09T12:34:56.000Z

  responses:
    WebhookResponse:
      description: Your endpoint should respond with a 2xx status code within 15 seconds. Long-running processing should be handled asynchronously.

    DuplicateExternalReferenceIdResponse:
      description: The provided external reference ID already exists within the authenticated API integration.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          examples:
            duplicate_external_reference_id:
              summary: Duplicate external reference ID
              value:
                code: duplicate_external_reference_id
                message: The external reference id already exists for this integration.

    SyncScanTimeoutResponse:
      description: The synchronous polling window timed out before a terminal result was available. Use `file_scan_id` to continue polling through the status endpoints.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/SyncScanTimeoutError'
          examples:
            sync_scan_timeout:
              summary: Synchronous scan timeout
              value:
                code: sync_scan_timeout
                message: The file scan is taking longer than expected. You can continue to check the status of this scan using its ID via the status endpoint.
                file_scan_id: 019583d8-b2e4-7b8d-9d1f-6f4cb3d0b6f1
