openapi: 3.0.1
info:
  title: Message Service API
  description: "This page describes how to integrate with the Message Service on a
    technical level.\n[**The Foundation API Guide**](../../../docs/api-guides/platform/foundation)
    provides a higher level overview of what messages are.\n\n## REST resources\n\n
    The resources of message service are Messages, Message Filters, and Event Sources.\n
    This section discusses those resources.\n\n### Message\n\nMessages enable asynchronous
    communication between components of the Banqup platform.\n\nAn example of a message
    as it will be received by listeners:\n\n```json\n{\n  \"id\": \"41b86461-2c30-4cc6-8892-ea342d2e546b\"\
    ,\n  \"audience\": \"someAudience\",\n  \"category\": \"myMessageCategory\",\n\
    \  \"type\": \"typeInCategory\",\n  \"scope\": \"myScope\",\n  \"subject\": \"\
    mySubject\",\n  \"resourceId\": \"d6a10e10-17c9-4081-9f54-8a218f00eba8\",\n  \"\
    channel\": \"d6a10e10-17c9-4081-9f54-8a218f00eba8/bb23bbff-7326-462f-80bc-4a3c5d66567e\"\
    ,\n  \"data\": {\n    \"paymentSuccessful\": true,\n    \"relatedDocumentId\"
    : \"bb23bbff-7326-462f-80bc-4a3c5d66567e\"\n  }\n}\n```\n\nMost of the fields
    of a message are optional and therefore only available if set by the sender.\n
    Refer to the documentation about [**Sending a message**](../../../docs/foundation/message/send-message-v-2)
    for more information about the fields.\nThe messages sent by the different Banqup's
    services are in their respective API specifications.\n\n\n### Message Filter\n
    \nMessage Filters are applied before a message is delivered to a message listener.\n
    In other words, a Message Filter limits what messages are delivered to a message
    listener.\nMessage senders, as well as message listeners, can register Message
    Filters.\n\nSenders will usually configure Message Filters for security reasons.\n
    For example, \"this message must only be published to subjects who hold a certain
    permission\".\nTo configure such a Message Filter, the sender will configure a
    _Message Authorizer_.\nA Message Authorizer returns Message Filters when called.\n
    For more information, refer to [**the guide on message authorizers**](../../../docs/api-guides/foundation/message-authorizers).\n
    \nMessage listeners will usually configure Message Filters because they only have
    a limited interest in messages of a certain category.\nFor example, \"only deliver
    messages if they are of category `myCategory` and of type `DocumentCreated`\"
    .\nThese Message Filters are configured the moment a message listener registers
    itself as a listener.\n\n#### Message Filter set by sender (Message Authorizer)\n
    \nMessage Filters can be defined on any of the field of a message.\n\n##### Example
    - user/permission filter\nThis is the most common Message Filter used by senders:\n\
    \n```json\n{\n  \"permissionFilterList\": [\n    {\n      \"type\": \"PERMISSION\"\
    ,\n      \"subject\": \"ba2c8c09-3e43-4650-94dd-a80e0257b201\"\n    }\n  ]\n}\n
    ```\n\nThe above permission filter, when applied, will only allow for messages
    to be received by message listeners for whom a specific permission exists.\nThat
    permission is the combination of the subjectId that was used to register the message
    listener, i.e. ba2c8c09-3e43-4650-94dd-a80e0257b201, the `scope` specified on
    the message that is to be sent, and the `resource` specified in the message.\n
    Therefore this filter only works if the message sender sends messages that have
    the fields `scope` and `resource` set.\nFor more information on permissions, see
    [**the guide on permissions**](../../../docs/api-guides/workspace/users/user-permissions).\n
    \n\nThe subjectId of a message listener will be read from the oauth token that
    is passed to Plugin Service when a message listener is registered.\nIf the message
    sender has a permission filter configured, such as the one above, this subjectId
    will be used to filter messages before they are sent to the receiver.\nIn this
    case, because the permission filter checks is a permission, which is the 3-tuple
    `(<subjectId>,<resourceId>,<scope>)`, all messages that are sent, must have the
    fields `resourceId` and `scope` defined in order for the permission filter to
    do its work.\nAn example of a message that will be permitted by the above Message
    Filter, assuming the subject's permissions are configured as described:\n\n```json\n\
    {\n  \"messageId\": \"41b86461-2c30-4cc6-8892-ea342d2e546b\",\n  \"category\"
    : \"myCategory\",\n  \"resourceId\": \"3716a9f4-0a36-4a51-a784-b6cfe466a51e\"\
    ,\n  \"scope\": \"904e1f90-7cd8-4dfe-bd10-34ed8f81fb81\",\n  \"data\": {\n   \
    \ \"documentId\": \"bb23bbff-7326-462f-80bc-4a3c5d66567e\"\n  }\n}\n```\n\nThe
    message in the above example will only be sent to message listeners that were
    registered with a subjectId for which the permission 3-tuple `(ba2c8c09-3e43-4650-94dd-a80e0257b201,3716a9f4-0a36-4a51-a784-b6cfe466a51e,904e1f90-7cd8-4dfe-bd10-34ed8f81fb81)`
    exists in the specified UMA-audience.\n\nBecause these this Message Filters commonly
    occurs, Message Service has [**an available endpoint**](../../../docs/foundation/message/get-permission-message-authorizer)
    that will return this Message Filter when called.\n\n##### Example - subject filter\n
    Another common Message Filter is a subject filter:\n\n```json\n{\n  \"permissionFilterList\"\
    : [\n    {\n      \"type\": \"SUBJECT\",\n      \"subject\": \"mySubjectId\"\n\
    \    }\n  ]\n}\n```\n\nThis Message Filter, when applied, will only allow for
    messages to be received by message listeners that were registered by subjects
    whose subjectId is equal to `mySubjectId`.\nThe subjectId of a message listener
    will be read from the oauth token that is passed to Plugin Service when a message
    listener is registered.\nAn example. Assuming the listener's subjectId is `ba2c8c09-3e43-4650-94dd-a80e0257b201`.\n\
    Let's also assume that a message sender has configured the following Message Filter:\n\
    \n```json\n{\n  \"permissionFilterList\": [\n    {\n      \"type\": \"SUBJECT\"\
    ,\n      \"subject\": \"ba2c8c09-3e43-4650-94dd-a80e0257b201\"\n    }\n  ]\n}\n
    ```\n\nWhen the message sender sends the following message, only message listeners
    that were registered by the subject with id `ba2c8c09-3e43-4650-94dd-a80e0257b201`
    will receive it:\n\n```json\n{\n  \"messageId\": \"41b86461-2c30-4cc6-8892-ea342d2e546b\"\
    ,\n  \"category\": \"myCategory\",\n  \"subject\": \"ba2c8c09-3e43-4650-94dd-a80e0257b201\"\
    ,\n  \"data\": {\n    \"documentId\": \"bb23bbff-7326-462f-80bc-4a3c5d66567e\"\
    \n  }\n}\n```\n\nBecause these this Message Filters commonly occurs, Message Service
    has [**an available endpoint**](../../../docs/foundation/message/get-subject-message-authorizer)
    that will return this Message Filter when called.\n\n### Event Sources\n\nEvent
    sources work as described in Server Sent Events (SSE), see  [**MDN docs**](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)
    for more information.\nAn event source has a set of subscriptions, see below.\n
    Calling the [**receive events endpoint**](../../../docs/foundation/channel/receive-events)
    of an event source opens an SSE stream which will deliver the desired messages
    as SSE-events.\nA typical usecase for event sources is a frontend web/mobile application
    that wants to update what it displays as soon as possible with little overhead.\n
    \nContrary to regular REST delivery, the events of event sources have a strict
    order.\nAs a consequence, event sources support the `Last-EventID` header.\nThis
    header will let the event source replay messages in case the receiver missed any.\n
    The number of messages that can be replayed is limited.\nIf a `Last-EventID` is
    submitted that the event source does not know, or if the ID is too old, the event
    source will return a HTTP 404 status code.\n\nTo create a new event source, see
    the documentation on [**the create event source endpoint**](../../../docs/foundation/channel/create-event-source).\n
    \n### Subscriptions\n\nSubscriptions determine which events will be delivered
    when someone calls the [**receive events endpoint**](../../../docs/foundation/channel/receive-events)
    of the event source they belong to.\nIn order to do so, each subscription has
    a set of [**Message Filters**](../../../docs/foundation/message/message-service-api#filtering-messages).\n
    All Message Filters of a single subscription are combined with boolean AND-logic.\n
    Event sources will deliver messages of all subscriptions.\nIn other words, subscriptions
    are combined with boolean OR-logic.\nIn typical use cases, a subscription will
    filter on a message category and/or type first, and then on a channel.\n\n**Example:**
    An application that wants to subscribe to events for messages of type `myType`,
    category `myCategory` in channel `myChannel`, will register the following subscription:\n\
    \n```json\n{\n  \"subscriptions\": [\n    {\n    \"filters\": [\n      {\n   \
    \     \"type\": \"CATEGORY\",\n        \"test\": [\n          \"myCategory\"\n\
    \        ]\n      },\n      {\n        \"type\": \"TYPE\",\n        \"test\":
    [\n          \"myType\"\n        ]\n      },\n      {\n        \"type\": \"CHANNEL\"\
    ,\n        \"test\": [\n          \"myChannel\"\n        ]\n      }\n    ]\n \
    \ }\n}\n```\n\n**Example:** If that same application wants to also receive events
    for message of type `myOtherType`, category `myOtherCategory` in channel `myOtherchannel`,
    it can create a __second__ subscription in the same request as follows:\n```json\n\
    {\n  \"subscriptions\": [\n        {\n    \"filters\": [\n      {\n        \"\
    type\": \"CATEGORY\",\n        \"test\": [\n          \"myCategory\"\n       \
    \ ]\n      },\n      {\n        \"type\": \"TYPE\",\n        \"test\": [\n   \
    \       \"myType\"\n        ]\n      },\n      {\n        \"type\": \"CHANNEL\"\
    ,\n        \"test\": [\n          \"myChannel\"\n        ]\n      }\n    ]\n \
    \ },\n    {\n    \"filters\": [\n      {\n        \"type\": \"CATEGORY\",\n  \
    \      \"test\": [\n          \"myOtherCategory\"\n        ]\n      },\n     \
    \ {\n        \"type\": \"TYPE\",\n        \"test\": [\n          \"myOtherType\"\
    \n        ]\n      },\n      {\n        \"type\": \"CHANNEL\",\n        \"test\"\
    : [\n          \"myOtherChannel\"\n        ]\n      }\n    ]\n  }\n}\n```\n\n
    ### Message Authorizer\n\nPlease refer to [**the guide on message authorizers**](../../../docs/api-guides/foundation/message-authorizers)
    for more information.\n\n## Listening to Messages\n\nThis section shows how an
    application can receive messages that are sent on the Banqup Platform.\nRoughly
    speaking, that will require the following steps:\n\n1. Create an endpoint that
    the Message Service can deliver messages to.\n2. Register the application as a
    Plugin of the Message Listener Plugin Interface.\n3. (Optional) configure your
    Plugin with Message Filters.\n\n\n### Registering a Message Listener\nCheck out
    the recipe [**Set Up A Message Listener**](../../../docs/recipes/platform/set-up-message-listener)
    to learn how to register a message listener.\n\n### Filtering messages\n\nMessage
    listeners may request to not receive all messages of a certain category.\nThis
    type of receiver side filtering can be configured when an application registers
    itself with the Plugin Service as a listener.\nConsequently, it can also be updated
    at any point in time by calling the Plugin Service API.\n\nFor message listeners,
    the most useful filters are `category` and `type`.\nOne additional filter `channel`
    can be interesting in specific use cases as well.\nA channel is a string that
    the sender can use to relate the message to some other object.\nChannel filters
    can filter messages that start with a specific value, so channels are often hierarchical.\n
    For a `DocumentUpdated` event for example, the channel value is the spaceId followed
    by the document's id.\nThis allows listeners to filter messages related to a specific
    space or to a specific document.\n\nA few examples of how Message Filters may
    be used follow.\n\n**Example:** an application with the following Message Filter
    would only receive messages of category `myCategory` and `myOtherCategory`.\n
    It therefore registers itself with the following Message Filter:\n\n```json\n\
    {\n  \"type\": \"CATEGORY\",\n  \"test\": [\n    \"myCategory\",\n    \"myOtherCategory\"\
    \n  ]\n}\n```\n\n**Example:** an application that wants to register itself as
    a message listener with the Plugin Service would then submit a request body like:\n\
    ```json\n{\n  \"data\": {\n    \"basePath\": \"https://example.com/my/callback/url\"\
    ,\n    \"filters\": [\n      {\n        \"type\": \"CATEGORY\",\n        \"test\"\
    : [\n          \"myCategory\"\n        ]\n      }\n    ]\n  }\n}\n```\n\n**Example:**
    an application with the the following filter will only receive messages of type
    `myType`:\n\n```json\n{\n  \"type\": \"TYPE\",\n  \"test\": [\n    \"myType\"\n\
    \  ]\n}\n```\n\n\n**Example:** an application that wants to register itself as
    a message listener with the Plugin Service would then submit a request body like:\n\
    ```json\n{\n  \"data\": {\n    \"basePath\": \"https://example.com/my/callback/url\"\
    ,\n    \"filters\": [\n      {\n        \"type\": \"TYPE\",\n        \"test\"
    : [\n          \"myType\"\n        ]\n      }\n    ]\n  }\n}\n```\n\nMultiple
    filters can also be configured at the same time.\nAt this time, these filters
    are applied with boolean AND logic exclusively.\n\n**Example:** An application
    that only wants to receive messages of type `myType` if they originate from category
    `myCategory`, would register with the Plugin Service with the following request
    body:\n\n```json\n{\n  \"data\": {\n    \"basePath\": \"https://example.com/my/callback/url\"\
    ,\n    \"filters\": [\n      {\n        \"type\": \"CATEGORY\",\n        \"test\"\
    : [\n          \"myCategory\"\n        ]\n      },\n      {\n        \"type\"
    : \"TYPE\",\n        \"test\": [\n          \"myType\"\n        ]\n      }\n \
    \   ]\n  }\n}\n```\n\n**Example:** Likewise, an application that wants to receive
    messages of type `myType`, category `myCategory` in channel `myChannel`, would
    register with the Plugin Service with the following request body:\n\n```json\n\
    {\n  \"data\": {\n    \"basePath\": \"https://example.com/my/callback/url\",\n\
    \    \"filters\": [\n      {\n        \"type\": \"CATEGORY\",\n        \"test\"\
    : [\n          \"myCategory\"\n        ]\n      },\n      {\n        \"type\"
    : \"TYPE\",\n        \"test\": [\n          \"myType\"\n        ]\n      },\n\
    \      {\n        \"type\": \"CHANNEL\",\n        \"test\": [\n          \"myChannel\"\
    \n        ]\n      }\n    ]\n  }\n}\n```\n\n### Ordered vs unordered message delivery\n
    \nMessages can be delivered in any order, or in the exact order the message service
    received requests to send them.\nThe former is done exclusively by REST endpoints.\n
    The latter is done exclusively by Google Cloud PubSub.\n\n#### Regular (unordered)
    delivery / REST\n\nTo register a listener that receives messages from the category
    `myCategory`, register a new plugin of the message listener plugin interface in
    the Plugin Service with the following request body:\n\n```json\n{\n  \"data\"
    : {\n    \"basePath\": \"https://example.com/messageListener\",\n    \"filters\"\
    : [\n      {\n        \"type\": \"CATEGORY\",\n        \"test\": [\n         \
    \ \"myCategory\"\n        ]\n      }\n    ]\n  }\n}\n```\n\nWhen a message is
    sent for `myCategory`, the Message Service will perform a **POST** on https://example.com/messageListener/messages
    with the content of the message it wants to deliver.\nNote the **/messages** subpath.\n
    The delivery is considered successful when the REST endpoint the message is delivered
    to returns a HTTP 2xx status code.\n\nIn the above example, the endpoint https://example.com/messageListener/messages
    will need to implement an endpoint that adheres to the message listener OpenAPI
    spec, available [here](https://TODO-link).\n\n##### Retries\n\nUnordered deliveries
    are retried for up to 48 hours.\n\nDuring development, services like [**ngrok**](https://ngrok.com)
    or [**webhook.site**](https://webhook.site) may be used.\nSince these endpoints
    are temporary in nature, listeners that return error response codes upon delivery
    will no longer be retried after 2 hours instead of the usual 48 hours.\nFurthermore
    ngrok and webhook.site listeners are removed after 2 hours of unsuccessful deliveries
    alltogether.\nUsers will not receive a notification of this removal.\n\n\n####
    Ordered delivery / PubSub\n\nA regular delivery is considered successful when
    the destination Google PubSub Topic accepts the delivery (HTTP 2xx status code).\n
    \nOrdered deliveries are never retried.\nIf they fail, the message listener is
    de-registered immediately.\nIf the message listener configured an `ownerEmail`
    when they registered their message listener, the owner will receive an e-mail
    notifying them about removal.\nTherefore the request body of an message listener
    with ordered delivery that wants to be notified when it is automatically removed
    will look like:\n\n```json\n{\n  \"data\": {\n    \"ownerEmail\": \"owneremail@example.com\"\
    ,\n    \"topicName\": \"projects/my-google-cloud-project/topics/topic-name\",\n\
    \    \"filters\": [\n      {\n        \"type\": \"CATEGORY\",\n        \"test\"\
    : [\n          \"myCategory\"\n        ]\n      }\n    ]\n  }\n}\n```\n\n## Sending
    messages\n\nThis REST call sends notifications related to events performed on
    the platform to other listening components that are registered with one or more
    plugin interfaces.\n\n### Request\n\nTo send a message, perform **POST** on [**/core/message/v2/messages:send**](../../../docs/foundation/message/send-message-v-2).\n
    The request body of this request must be a message and will be sent as such to
    message listeners.\n\n**Request body** (application/json):\n\n```json\n{\n  \"\
    audience\": \"someAudience\",\n  \"category\": \"myMessageCategory\",\n  \"type\"\
    : \"typeInCategory\",\n  \"scope\": \"document_read\",\n  \"subject\": \"ba2c8c09-3e43-4650-94dd-a80e0257b201\"\
    ,\n  \"resourceId\": \"d6a10e10-17c9-4081-9f54-8a218f00eba8\",\n  \"channel\"
    : \"d6a10e10-17c9-4081-9f54-8a218f00eba8/bb23bbff-7326-462f-80bc-4a3c5d66567e\"\
    ,\n  \"orderGroup\": \"myOrderGroup\",\n  \"data\": {\n    \"paymentSuccessful\"\
    : true,\n    \"relatedDocumentId\": \"bb23bbff-7326-462f-80bc-4a3c5d66567e\"\n\
    \  }\n}\n```\n\nRefer to the documentation about [**Sending a message**](../../../docs/foundation/message/send-message-v-2)
    for more information about the meaning of these fields.\n\n**Response**\nA successful
    202 response returns the message ID, confirming that the message has been sent
    and will be sent to all subscribed message listeners.\n\n```json\n{\n  \"id\"
    : \"41b86461-2c30-4cc6-8892-ea342d2e546b\"\n}\n```\n\nThis ID can be used as a
    correlation ID.\nApplications can safely use it to determine whether or not a
    message has already been received.\n\n### Security\n\nIn order to send a message,
    the sender must hold the permission `(<subject>,<resource>,<scope>)` = `(<sender
    subjectId>, <name of value of the category propery in the message >, message_category_send)`.\n
    Once you hold this permission, and without any further steps, any message that
    is sent by the sender will be delivered to any application that has registered
    itself as a message listener.\nOf course, this assumes that the Message Filters
    are configured correctly.\n\nTo limit who can receive messages of a certain category,
    implement the message authorizer plugin interface.\nThey can then apply filters
    at will, see also [**Message Filter set by sender (Message Authorizer)**](../../../docs/foundation/message/message-service-api#message-filter-set-by-sender-message-authorizer).\n
    \nRight before a message is published to a listener, any Message Filters created
    by the Message Authorizer are applied. \nIf those Message Filters do not block
    the message, the receiver will receive it.\nChanges to the authorization of a
    listener propagate through the system after a brief delay (<1min).\n"
  version: 2.0.0
servers:
- description: The Message Service API REST endpoint via localtest.me
  url: https://api.cve.btx.eu.banqup.com/core/message
paths:
  /v2/messages:send:
    post:
      tags:
      - Message Service
      summary: Send a message
      description: |-
        Sends a message to all listeners that are authorized to receive it.
         <br/> Scope: []<br/> This Endpoint is part of: message-service
      operationId: sendMessageV2
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendMessageRequest'
        required: true
      responses:
        '202':
          description: |
            The message has been accepted and will soon be sent to all subscribed message listeners.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '403':
          description: |
            You must have the permission 'message_category_send' on the category that is in your request.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
  /v1/messages:
    post:
      tags:
      - Message Service
      summary: '[DEPRECATED] Send a message'
      description: |
        Sends a message to all listeners that are authorized to receive it.
        **Deprecated** due to API rework. Use /v2/messages:send instead.
      operationId: sendMessage
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MessageRequest'
        required: true
      responses:
        '202':
          description: |
            The message has been accepted and will soon be sent to all subscribed message listeners.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '403':
          description: |
            You must have the permission 'message_category_send' on the category that is in your request.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
      deprecated: true
components:
  schemas:
    JsonNode:
      type: object
      description: |
        Free-form JSON object containing data relevant to the message.
      example:
        paymentSuccessful: true
        relatedDocumentId: bb23bbff-7326-462f-80bc-4a3c5d66567e
    SendMessageRequest:
      required:
      - category
      type: object
      properties:
        resourceId:
          maxLength: 256
          minLength: 0
          type: string
          description: |
            Resource for which a message is relevant. Used for authorization checks, usually refers to a space ID.
          example: d6a10e10-17c9-4081-9f54-8a218f00eba8
        scope:
          maxLength: 256
          minLength: 0
          type: string
          description: |
            Refers to the permission intended recipients of the message needs to have (e.g., `document_read`, `file_read`).
            The subject (user), together with the resource (space) and the scope, define which listener should receive which messages.
          example: document_read
        category:
          maxLength: 1024
          minLength: 0
          type: string
          description: |
            Refers to the high-level classification of the different actions that can trigger messages (e.g., 'documents').
            Sending a message in a category requires the sender to have a category-specific 'message_category_send' permission
          example: myMessageCategory
        channel:
          maxLength: 256
          minLength: 0
          type: string
          description: |
            Channel filters can filter messages that start with a specific value.
            Channel must be filled in when messages need to arrive to front-end applications via SSE.
            Channel is a refinement of category.
            For example, when category is `document`, channel could be the relevant space ID + document ID so that frontend applications can be notified of all events concerning the document currently on display (eg `updated`, `deleted`, `added`, `paid`, etc, ) by subscribing to a given channel.
            Channel filters work hierarchically: a frontend could, for example, subscribe to `document/spaceID/documentID` to receive all events of category `document` pertaining to a specific document, or subscribe to `document/spaceID` to receive all events of category `document` pertaining to an entire space.
          example: |
            d6a10e10-17c9-4081-9f54-8a218f00eba8/bb23bbff-7326-462f-80bc-4a3c5d66567e
        type:
          maxLength: 64
          minLength: 0
          type: string
          description: |
            Refers to the subsets of a category (e.g., `DocumentCreated`, `DocumentUpdated`, `DocumentDeleted`).
            Types can be freely created within a category the sender has access to.
          example: DocumentCreated
        audience:
          maxLength: 256
          minLength: 0
          type: string
          description: |
            Audience that the permission belongs to.
            By default, this will be `btx-auth`.
            If that is not a sender's need, they may overrule this audience and fill out another one.
          example: btx-auth
        subject:
          maxLength: 256
          minLength: 0
          type: string
          description: "\t\tThe subject the sender would like to communicate with.\n
            \t\tCan be used for authorization checks before messages are sent.\n"
          example: ba2c8c09-3e43-4650-94dd-a80e0257b201
        orderGroup:
          maxLength: 256
          minLength: 0
          pattern: .*\S.*
          type: string
          description: |
            Exclusively for ordered messages.
            Order groups define what messages belong together and are used to enforce restrictions on the order in which messages are delivered to ordered listeners.
            Messages with the same orderGroup value will be delivered in the order they are received.
            Messages with different orderGroups or without an orderGroup can be received out of order.
            If no orderGroup is set, Banqup will generate one and you may not have the expected message ordering.
          example: bb23bbff-7326-462f-80bc-4a3c5d66567e
        data:
          $ref: '#/components/schemas/JsonNode'
    ProblemDetail:
      type: object
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
          format: int32
        detail:
          type: string
        instance:
          type: string
          format: uri
        properties:
          type: object
          additionalProperties:
            type: object
    MessageResponse:
      required:
      - messageId
      type: object
      properties:
        messageId:
          minLength: 1
          type: string
          description: |
            The message will be delivered with this ID to Message Listeners.
            This ID may be used as a correlation ID.
          example: 41b86461-2c30-4cc6-8892-ea342d2e546b
    MessageRequest:
      required:
      - category
      type: object
      properties:
        resourceId:
          maxLength: 256
          minLength: 0
          type: string
        scope:
          maxLength: 256
          minLength: 0
          type: string
        category:
          maxLength: 1024
          minLength: 0
          type: string
        channel:
          maxLength: 256
          minLength: 0
          type: string
        type:
          maxLength: 64
          minLength: 0
          type: string
        audience:
          maxLength: 256
          minLength: 0
          type: string
        subject:
          maxLength: 256
          minLength: 0
          type: string
        orderGroup:
          maxLength: 256
          minLength: 0
          pattern: .*\S.*
          type: string
        data:
          $ref: '#/components/schemas/JsonNode'
  securitySchemes:
    oauth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://api.cve.btx.eu.banqup.com/oauth2/client_credential/gettoken
          scopes:
            info: Scopes are endpoint-specific, see each endpoint for required scope.
        authorizationCode:
          authorizationUrl: https://api.cve.btx.eu.banqup.com/oauth2/auth
          tokenUrl: https://api.cve.btx.eu.banqup.com/oauth2/token
          scopes:
            info: Scopes are endpoint-specific, see each endpoint for required scope.
