Sublime Security Messages API

The Messages API from Sublime Security — 19 operation(s) for messages.

OpenAPI Specification

sublime-security-messages-api-openapi.yml Raw ↑
openapi: 3.0.1
info:
  contact:
    email: support@sublime.security
  title: Multi-Tenancy API (BETA) BinExplode Messages API
  version: ''
servers:
- url: '{scheme}://{server}'
  variables:
    scheme:
      default: https
      enum:
      - http
      - https
    server:
      default: platform.sublime.security
      description: Base URL of your Sublime deployment
security:
- bearerAuth: []
tags:
- name: Messages
paths:
  /v0/messages/analyze:
    post:
      description: 'Analyze a raw message with provided rules and/or active rules in your Sublime organization. Note: All messages will be treated as inbound.'
      operationId: analyzeMessage
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnalyzeMessageInput'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesAnalyzeRawMessageResponse'
          description: OK
      summary: Analyze a raw message
      tags:
      - Messages
  /v0/messages/attachment/image:
    post:
      description: Render image for attachment from the raw base64 encoded bytes
      operationId: getMessageAttachmentImageRaw
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GetMessageAttachmentImageRawInput'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesAttachmentImageContent'
          description: OK
      summary: Render image for attachment from the raw base64 encoded bytes
      tags:
      - Messages
  /v0/messages/attack_score:
    post:
      description: Evaluate attack score for a raw message
      operationId: attackScoreForRawMessage
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AttackScoreForRawMessageInput'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HandlersAttackScoreResponse'
          description: OK
      summary: Evaluate attack score for a raw message
      tags:
      - Messages
  /v0/messages/create:
    post:
      description: Create a new message data model from a raw message
      operationId: createMessage
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMessageInput'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HandlersMessage'
          description: OK
      summary: Create message
      tags:
      - Messages
  /v0/messages/groups/{id}/action-state:
    get:
      description: Retrieve details about the state of manual actions for a canonical group
      operationId: getMessageCanonicalGroupActionState
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      - description: Only return action states created after this time
        in: query
        name: created_at__gte
        schema:
          description: Only return action states created after this time
          format: date-time
          nullable: true
          type: string
      - description: The maximum number of action states to return. If the value exceeds the maximum, then the maximum value will be used.
        in: query
        name: limit
        schema:
          default: 10
          description: The maximum number of action states to return. If the value exceeds the maximum, then the maximum value will be used.
          format: int32
          maximum: 50
          type: integer
      - description: The (zero-based) offset of the action states to return
        in: query
        name: offset
        schema:
          default: 0
          description: The (zero-based) offset of the action states to return
          format: int32
          type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HandlersGetMessageCanonicalGroupTasksResponse'
          description: OK
      summary: Retrieve details about the state of manual actions for a canonical group
      tags:
      - Messages
  /v0/messages/{id}:
    get:
      description: Retrieve a message
      operationId: getMessage
      parameters:
      - in: path
        name: id
        required: true
        schema:
          format: uuid
          type: string
      - description: When true, recompute the MDM from the raw EML. For internal use only!
        in: query
        name: recompute_mdm_from_raw
        schema:
          description: When true, recompute the MDM from the raw EML. For internal use only!
          nullable: true
          type: boolean
      - description: When true, any text field over 1MB will be cleared before returning
        in: query
        name: remove_large_text_fields
        schema:
          description: When true, any text field over 1MB will be cleared before returning
          nullable: true
          type: boolean
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesMessage'
          description: OK
      summary: Retrieve message
      tags:
      - Messages
  /v0/messages/{id}/actions:
    post:
      description: Perform actions (trash, restore, quarantine, warning banner, move to spam) on an individual message
      operationId: actionMessage
      parameters:
      - description: ID of the message to act on
        in: path
        name: id
        required: true
        schema:
          description: ID of the message to act on
          format: uuid
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActionMessageInput'
      responses:
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesTaskAccepted'
          description: Accepted
      summary: Perform actions on an individual message
      tags:
      - Messages
  /v0/messages/{id}/analyze:
    post:
      description: Analyze a message by ID with provided rules and/or active rules in your Sublime organization
      operationId: analyzeMessageByID
      parameters:
      - description: The ID of the message
        in: path
        name: id
        required: true
        schema:
          description: The ID of the message
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnalyzeMessageByIDInput'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesAnalyzeRawMessageResponse'
          description: OK
      summary: Analyze a message by ID
      tags:
      - Messages
  /v0/messages/{id}/asa_report:
    get:
      description: Retrieve ASA report for a message
      operationId: retrieveASAReport
      parameters:
      - description: Message ID
        in: path
        name: id
        required: true
        schema:
          description: Message ID
          format: uuid
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HandlersAsaReportResponseV0'
          description: OK
      summary: Retrieve ASA report for a message
      tags:
      - Messages
  /v0/messages/{id}/asa_verdict:
    get:
      description: Retrieve ASA verdict for a message
      operationId: retrieveASAVerdict
      parameters:
      - description: Message ID
        in: path
        name: id
        required: true
        schema:
          description: Message ID
          format: uuid
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HandlersAsaVerdictResponseV0'
          description: OK
      summary: Retrieve ASA verdict for a message
      tags:
      - Messages
  /v0/messages/{id}/attachment/{hash}/image:
    get:
      description: Retrieve image of PDF attachment by md5 hash
      operationId: getMessageAttachmentImage
      parameters:
      - description: MD5 hash of the attachment to retrieve
        in: path
        name: hash
        required: true
        schema:
          description: MD5 hash of the attachment to retrieve
          type: string
      - description: Sublime Message ID
        in: path
        name: id
        required: true
        schema:
          description: Sublime Message ID
          format: uuid
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesAttachmentImageContent'
          description: OK
      summary: Retrieve image of PDF attachment by md5 hash
      tags:
      - Messages
  /v0/messages/{id}/attack_score:
    get:
      description: Evaluate attack score against an existing message
      operationId: attackScoreForMessage
      parameters:
      - description: Message ID
        in: path
        name: id
        required: true
        schema:
          description: Message ID
          format: uuid
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HandlersAttackScoreResponse'
          description: OK
      summary: Evaluate attack score against an existing message
      tags:
      - Messages
  /v0/messages/{id}/eml:
    get:
      description: Retrieve the raw EML for the message
      operationId: getMessageEML
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
      summary: Retrieve raw EML
      tags:
      - Messages
  /v0/messages/{id}/image:
    get:
      description: Retrieve an image of the message
      operationId: getMessageImage
      parameters:
      - in: path
        name: id
        required: true
        schema:
          format: uuid
          type: string
      - description: When true, recompute the MDM from the raw EML. For internal use only!
        in: query
        name: recompute_mdm_from_raw
        schema:
          description: When true, recompute the MDM from the raw EML. For internal use only!
          nullable: true
          type: boolean
      - description: When true, any text field over 1MB will be cleared before returning
        in: query
        name: remove_large_text_fields
        schema:
          description: When true, any text field over 1MB will be cleared before returning
          nullable: true
          type: boolean
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesMessageImage'
          description: OK
      summary: Retrieve image of message
      tags:
      - Messages
  /v0/messages/{id}/image_link:
    get:
      description: Retrieve a temporary link to the image of the message
      operationId: getMessageImageLink
      parameters:
      - in: path
        name: id
        required: true
        schema:
          format: uuid
          type: string
      - description: Period link should be valid for. Default is 15 minutes, max 7 days.
        in: query
        name: link_duration_seconds
        schema:
          description: Period link should be valid for. Default is 15 minutes, max 7 days.
          format: int32
          maximum: 604800
          nullable: true
          type: integer
      - allowEmptyValue: true
        description: When true, link will always be presigned against Sublime. When false, the link may be to S3 directly.
        in: query
        name: platform_link
        schema:
          description: When true, link will always be presigned against Sublime. When false, the link may be to S3 directly.
          type: boolean
      - description: When true, recompute the MDM from the raw EML. For internal use only!
        in: query
        name: recompute_mdm_from_raw
        schema:
          description: When true, recompute the MDM from the raw EML. For internal use only!
          nullable: true
          type: boolean
      - description: When true, any text field over 1MB will be cleared before returning
        in: query
        name: remove_large_text_fields
        schema:
          description: When true, any text field over 1MB will be cleared before returning
          nullable: true
          type: boolean
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesMessageImageLink'
          description: OK
      summary: Retrieve a temporary link to the image of message
      tags:
      - Messages
  /v0/messages/{id}/justification:
    post:
      description: Set message contents access justification for a message for the user associated with the API key being used
      operationId: SetMessageAccessJustification
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetMessageAccessJustificationInput'
      responses:
        '200':
          description: OK
      summary: Set access justification
      tags:
      - Messages
  /v0/messages/{id}/message_data_model:
    get:
      description: Retrieve the message's Message Data Model. If there is no justification, it will be redacted.
      operationId: getMessageDataModel
      parameters:
      - in: path
        name: id
        required: true
        schema:
          format: uuid
          type: string
      - description: When true, recompute the MDM from the raw EML. For internal use only!
        in: query
        name: recompute_mdm_from_raw
        schema:
          description: When true, recompute the MDM from the raw EML. For internal use only!
          nullable: true
          type: boolean
      - description: When true, any text field over 1MB will be cleared before returning
        in: query
        name: remove_large_text_fields
        schema:
          description: When true, any text field over 1MB will be cleared before returning
          nullable: true
          type: boolean
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Mdm_serviceMessageDataModel'
          description: OK
      summary: Retrieve the message's Message Data Model
      tags:
      - Messages
  /v0/messages/{id}/restore:
    post:
      description: Restore a previously-trashed message. "For an Office 365 message source, the message will be put back in the folder it was in before. For a Google Workspace message source, any applied labels (e.g. "Trash") will be removed from the message."
      operationId: restoreMessage
      parameters:
      - description: ID of the message to restore
        in: path
        name: id
        required: true
        schema:
          description: ID of the message to restore
          format: uuid
          type: string
      responses:
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesTaskAccepted'
          description: Accepted
      summary: Restore a previously-trashed message
      tags:
      - Messages
  /v0/messages/{id}/trash:
    post:
      description: Trash a message. For an Office 365 message source, the message will be moved to the "Recoverable Items" folder. For a Google Workspace message source, the "Trash" label will be added to the message.
      operationId: trashMessage
      parameters:
      - description: ID of the message to trash
        in: path
        name: id
        required: true
        schema:
          description: ID of the message to trash
          format: uuid
          type: string
      responses:
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Handler_typesTaskAccepted'
          description: Accepted
      summary: Trash message
      tags:
      - Messages
components:
  schemas:
    Handler_typesAnalyzeRawMessageResponse:
      properties:
        query_results:
          description: Query result details
          items:
            $ref: '#/components/schemas/Handler_typesAnalyzeResponseQuery'
          type: array
        rule_results:
          description: Analyze result details
          items:
            $ref: '#/components/schemas/Handler_typesAnalyzeResponseRule'
          type: array
      type: object
    Mdm_serviceSPF:
      description: Details of the Sender Policy Framework check. Supported fields include 'Received-SPF' and 'X-Received-SPF'
      properties:
        client_ip:
          $ref: '#/components/schemas/Mdm_serviceIP'
        description:
          description: Verbose description of the SPF verdict
          nullable: true
          type: string
        designator:
          description: Email or domain of the designating body
          nullable: true
          type: string
        helo:
          $ref: '#/components/schemas/Mdm_serviceDomain'
        server:
          $ref: '#/components/schemas/Mdm_serviceDomain'
        verdict:
          description: Verdict of the SPF
          nullable: true
          type: string
      type: object
    Mdm_serviceIP:
      description: X-Originating-IP header, which identifies the originating IP address of the sender client
      properties:
        ip:
          description: The IP in canonical form
          type: string
        translation:
          $ref: '#/components/schemas/Mdm_serviceIPTranslation'
        version:
          description: The version of IP (i.e., 4 or 6), null for backward compatibility.
          format: int32
          nullable: true
          type: integer
      required:
      - ip
      type: object
    Mdm_serviceThreadRecipients:
      description: Recipients extracted from thread preamble
      properties:
        bcc:
          description: List of 'bcc' Mailbox objects
          items:
            $ref: '#/components/schemas/Mdm_serviceMailbox'
          type: array
        cc:
          description: List of 'cc' Mailbox objects
          items:
            $ref: '#/components/schemas/Mdm_serviceMailbox'
          type: array
        to:
          description: List of 'to' Mailbox objects
          items:
            $ref: '#/components/schemas/Mdm_serviceMailbox'
          type: array
      type: object
    Handler_typesAnalyzeResponseQuery:
      properties:
        error:
          description: Error message, if success == false
          nullable: true
          type: string
        execution_time:
          description: Execution time in seconds
          format: double
          nullable: true
          type: number
        external_errors:
          description: External errors that occurred during evaluation
          items:
            type: string
          type: array
        query:
          $ref: '#/components/schemas/Handler_typesQuerySimpleMeta'
        result:
          description: Result of the query evaluation
          nullable: true
        success:
          description: Whether execution was successful or errored
          type: boolean
      required:
      - execution_time
      - success
      type: object
    Mdm_serviceDMARC:
      description: Details of the Domain-based Message Authentication, Reporting & Conformance check
      properties:
        action:
          description: Indicates the action taken by the spam filter based on the results of the DMARC check. For more information see https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spam-message-headers?view=o365-worldwide#authentication-results-message-header-fields
          nullable: true
          type: string
        disposition:
          description: Gmail-applied policy
          nullable: true
          type: string
        from:
          $ref: '#/components/schemas/Mdm_serviceDomain'
        policy:
          description: Policy for the organizational domain
          nullable: true
          type: string
        sub_policy:
          description: Policy for the subdomain of the organizational domain
          nullable: true
          type: string
        verdict:
          description: Describes the results of the DMARC check for the message
          nullable: true
          type: string
        version:
          description: DMARC version
          nullable: true
          type: string
      type: object
    Mdm_serviceReceivedBy:
      description: The 'by' section of the Received header, denoting the current server
      properties:
        raw:
          description: The raw string of 'by' section
          type: string
      type: object
    Handler_typesRecipient:
      properties:
        email:
          description: Email address
          type: string
      required:
      - email
      type: object
    HandlersMessage:
      properties:
        canonical_group_id:
          description: Identifier shared by messages with the same canonical_id that arrive within the same period without a 60-minute gap
          type: string
        canonical_id:
          description: The sha1 hash of the message body text and sender
          type: string
        created_at:
          description: Datetime the message was created
          type: string
        data_model:
          $ref: '#/components/schemas/Mdm_serviceMessageDataModel'
        delivered_at:
          description: The time, if any, at which the message was delivered
          format: date-time
          nullable: true
          type: string
        effective_at:
          description: The effective time of the message
          format: date-time
          nullable: true
          type: string
        id:
          description: Message ID
          format: uuid
          type: string
        mailbox_id:
          description: ID of the mailbox for the message
          format: uuid
          nullable: true
          type: string
        matched_global_exclusion:
          description: Whether or not the message matched a global exclusion rule
          nullable: true
          type: boolean
        preview:
          $ref: '#/components/schemas/TypesPreview'
        raw_message_id:
          description: ID of the raw message that generated this message
          format: uuid
          type: string
        received_inline:
          description: Whether or not the message was received via inline processing
          type: boolean
        reports_as_phish:
          description: ID of the message group this message reports as phish
          nullable: true
          type: string
        reviewed_at:
          description: Datetime the message was reviewed
          nullable: true
          type: string
        status:
          description: The status of the message
          nullable: true
          type: string
        status_changed_at:
          description: The time when the status last changed
          format: date-time
          nullable: true
          type: string
        type:
          $ref: '#/components/schemas/TypesMessageType'
      required:
      - canonical_group_id
      - canonical_id
      - created_at
      - data_model
      - id
      - preview
      - raw_message_id
      type: object
    Mdm_serviceBodyHTML:
      description: The body part containing content-type text/html
      properties:
        charset:
          description: charset of the text/[subtype]
          type: string
        content_transfer_encoding:
          description: Content-Transfer-Encoding of the text/[subtype]
          type: string
        display_text:
          description: Visible text of the HTML document, with invisible characters removed and non-ASCII characters converted to ASCII spaces.
          nullable: true
          type: string
        inner_text:
          description: Inner text of the HTML document that doesn't include HTML tags.
          nullable: true
          type: string
        links:
          description: All links found in the HTML part of the body of the message
          items:
            $ref: '#/components/schemas/Mdm_serviceLink'
          type: array
        raw:
          description: Decoded raw content of a body text type (text/[subtype] section)
          nullable: true
          type: string
      type: object
    Mdm_serviceMessageType:
      description: Override on message types, defined from the perspective of your organization
      properties:
        inbound:
          description: Message was sent from someone outside your organization, to *at least one* recipient inside your organization
          type: boolean
        internal:
          description: Message was sent from someone inside your organization, to *at least one* recipient inside your organization. Messages *must be authenticated* by either SPF or DKIM to be treated as internal.
          type: boolean
        outbound:
          description: Message was sent from someone inside your organization, to *at least one* recipient outside your organization
          type: boolean
      type: object
    Handler_typesSender:
      description: Details of the message sender
      properties:
        display_name:
          description: Display name
          type: string
        email:
          description: Email address
          type: string
      required:
      - email
      type: object
    Mdm_serviceEmailAddress:
      description: Email address object
      properties:
        domain:
          $ref: '#/components/schemas/Mdm_serviceDomain'
        email:
          description: Full email address
          format: email
          type: string
        local_part:
          description: Local-part, i.e. before the @
          type: string
      type: object
    Mdm_serviceIPTranslation:
      properties:
        original:
          description: The IP in its original format if it is an IPv4-mapped-IPv6 source address
          nullable: true
          type: string
        v4_to_v6:
          description: Whether 'Original' is IPv4-mapped-IPv6
          type: boolean
      type: object
    AnalyzeMessageByIDInput:
      properties:
        queries:
          description: Queries to analyze
          items:
            $ref: '#/components/schemas/Handler_typesQuerySimple'
          type: array
        rules:
          description: Rules to analyze
          items:
            $ref: '#/components/schemas/Handler_typesRuleSimple'
          type: array
        run_active_detection_rules:
          default: false
          description: Whether to analyze the message with all active detection rules in your organization
          type: boolean
        run_all_detection_rules:
          default: false
          description: Whether to analyze with all detection rules from all Feeds, including uninstalled + inactive Feed rules, as well as any active detection rules you’ve created that are not part of a Feed.
          type: boolean
        run_all_insights:
          default: false
          description: Whether to analyze with all insights
          type: boolean
      type: object
    Mdm_serviceReceived:
      description: Details of the Received field
      properties:
        additional:
          $ref: '#/components/schemas/Mdm_serviceReceivedAdditional'
        id:
          $ref: '#/components/schemas/Mdm_serviceReceivedID'
        link:
          $ref: '#/components/schemas/Mdm_serviceReceivedVia'
        mailbox:
          $ref: '#/components/schemas/Mdm_serviceReceivedFor'
        protocol:
          $ref: '#/components/schemas/Mdm_serviceReceivedWith'
        server:
          $ref: '#/components/schemas/Mdm_serviceReceivedBy'
        source:
          $ref: '#/components/schemas/Mdm_serviceReceivedFrom'
        time:
          description: Time parsed from the Received header
          format: date-time
          nullable: true
          type: string
        zone_offset:
          description: Timezone offset parsed from the Received header
          nullable: true
          type: string
      type: object
    Mdm_serviceSubject:
      description: Subject object
      properties:
        base:
          description: Subject of the email with tags and reply/forward indicators removed
          type: string
        is_forward:
          description: Indicates if the subject of the email is a forward
          nullable: true
          type: boolean
        is_reply:
          description: Indicates if the subject of the email is a reply
          nullable: true
          type: boolean
        subject:
          description: Subject of the email
          type: string
        tags:
          description: Leading tags extracted from the subject, e.g. [External] or (Warning)
          items:
            type: string
          type: array
      type: object
    Mdm_serviceMailbox:
      description: Organizer mailbox with email and display name
      properties:
        display_name:
          description: Display name
          type: string
        email:
          $ref: '#/components/schemas/Mdm_serviceEmailAddress'
      required:
      - email
      type: object
    Handler_typesQuerySimple:
      properties:
        name:
          description: Query name
          nullable: true
          type: string
        severity:
          description: Severity associated with the query
          nullable: true
          type: string
        source:
          description: The MQL source to run against the message
          nullable: true
          type: string
      required:
      - source
      type: object
    Handler_typesMessageImage:
      properties:
        data:
          description: Base64-encoded image data
          format: byte
          type: string
        is_empty_body:
          description: If the message is missing a body. In this case an empty PNG is returned.
          type: boolean
        mime_type:
          description: MIME type of the image
          type: string
      type: object
    Handler_typesQuerySimpleMeta:
      description: Metadata about the query evaluated against the message
      properties:
        name:
          description: Query name
          nullable: true
          type: string
        severity:
          description: Severity associated with the query
          nullable: true
          type: string
        source:
          description: Query source
          nullable: true
          type: string
      type: object
    Mdm_serviceHop:
      properties:
        authentication_results:
          $ref: '#/components/schemas/Mdm_serviceAuthResults'
        fields:
          description: List of all raw header fields contained within this hop
          items:
            $ref: '#/components/schemas/Mdm_serviceHopField'
          type: array
        index:
          description: Index indicates the order in which a hop occurred from sender to recipient
          format: int32
          type: integer
        received:
          $ref: '#/components/schemas/Mdm_serviceReceived'
        received_spf:
          $ref: '#/components/schemas/Mdm_serviceSPF'
        signature:
          $ref: '#/components/schemas/Mdm_serviceSignature'
      required:
      - fields
      - index
      type: object
    Mdm_serviceReceivedAdditional:
      description: The remaining additional clauses of the Received header
      properties:
        raw:
          description: The raw string for remaining additional clauses, such as transport information
          type: string
      type: object
    TypesPreview:
      description: Preview of key details from the message header
      properties:
        attachment_sha256:
          description: SHA256 hashes of attachments
          items:
            type: string
          type: array
        recip

# --- truncated at 32 KB (73 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/sublime-security/refs/heads/main/openapi/sublime-security-messages-api-openapi.yml