openapi: 3.0.1
info:
  title: Mambu Audit Trail API V2
  description: |
    The Audit Trail V2 API provides access to audit events tracking all activities performed in the Mambu Core Banking Engine via UI or API.

    **Key Features:**
    - Track both read (GET) and write (POST, PUT, DELETE, PATCH) operations
    - Query up to 50,000 events per request
    - Filter by user, resource, time range, and more
    - Monitor compliance and security activities
    - Track quota usage with metadata endpoint

    **Authentication:**
    Requires an API key from an API Consumer with MANAGE_AUDIT_TRAIL permission.

    **Base URL:** `https://TENANT_NAME.mambu.com/api`
  contact:
    name: Mambu Support
    url: https://support.mambu.com
    email: support@mambu.com
  version: 2.0.0
servers:
  - url: "https://{tenant}.mambu.com/api"
    description: Production
    variables:
      tenant:
        description: Your Mambu tenant name
        default: demotenant
security:
  - ApiKeyAuth: []
tags:
  - name: Events v2
    description: Audit events query API (recommended)
  - name: Metadata
    description: Metadata and metrics for tenant audit events
paths:
  /v2/events:
    get:
      tags:
        - Events v2
      summary: Query audit events
      description: |
        Query audit events. This is the recommended V2 API.

        **Important Notes:**
        - Time range filters are **REQUIRED** (`occurred_at` with `gte`/`gt` and `lte`/`lt` operators).
        - Maximum time range per request: 30 days.
        - Default limit: 10,000 events (maximum: 50,000).
        - Rate limit: 1 request per second per tenant.
        - Results are ordered by `occurred_at` in ascending order.

        **Filter Syntax:** `FIELD_NAME[OPERATOR]=VALUE`

        ### Operators
        **Note:** The [Mambu API V2](/api/pages/api-v2/welcome) interprets URL encoded characters as literal strings. Customers who access the V2 API should use decoded strings directly. For example, `request_payload[contains]=%22viewType%22%3A%22CLIENT%22` will return an empty string. Use `request_payload[contains]="viewType":"CLIENT"` instead.

        |Operator|Description|Example|
        |------------|----------------|------------|
        |`eq`|Equals - exact match, applies to any type of fields.|`username[eq]=demo@mambu.com`|
        |`ne`|Not equals, applies to any type of fields.|`username[ne]=demo@mambu.com`|
        |`gt`|Greater than, applies to numeric or date fields.|`occurred_at[gt]=2018-05-01`|
        |`gte`|Greater than or equal, applies to numeric or date fields.|`occurred_at[gte]=2018-05-01`|
        |`lt`|Less than, applies to numeric or date fields.|`occurred_at[lt]=2018-05-01`|
        |`lte`|Less than or equal, applies to numeric or date fields.|`occurred_at[lte]=2018-05-01`|
        |`in`|Element in list (exact match), applies to any type of fields.|`username[in]=user1@mambu.com,user2@mambu.com`|
        |`contains`| Operator allows searching for specific substrings or variables within a field. It supports partial matches, making it possible to find results even if the exact value isn't provided. However, this operator does not support searching for multiple elements simultaneously.|`request_payload[contains]="provisionedThroughFederation"`|

        **Pagination:**
        When `hasMore: true` in the response, use the `nextStartTime` value as `occurred_at[gte]` for the next request.
      operationId: searchAuditEvents
      parameters:
        - name: "occurred_at[gte]"
          in: query
          description: "The timestamp, in UTC, when the event has been generated (when\
          \ creating queries on this field the provided values must be in ISO8601\
          \ standard). Supported operators: `gt`, `gte`, `lt`, `lte`."
          required: true
          schema:
            type: string
            format: date-time
          example: 2025-01-03T00:00:00Z
        - name: "occurred_at[lte]"
          in: query
          description: "The timestamp, in UTC, when the event has been generated (when\
          \ creating queries on this field the provided values must be in ISO8601\
          \ standard). Supported operators: `gt`, `gte`, `lt`, `lte`."
          required: true
          schema:
            type: string
            format: date-time
          example: 2025-01-04T23:59:59Z
        - name: limit
          in: query
          description: "The number of events that will be returned. By default, this\
          \ is 10,000 events. You can increase it up to 50,000 events. However, note\
          \ that latency will be increased with more events that need to be returned."
          schema:
            maximum: 50000
            minimum: 1
            type: integer
            format: int64
            default: 10000
          example: 10000
        - name: "event_source[eq]"
          in: query
          description: "The events that are supposed to be audited fall within the following\
          \ categories: `API`, `UI`. Supported operators: `eq`, `ne`, `in`."
          schema:
            type: string
            enum:
              - API
              - UI
          example: API
        - name: "resource[eq]"
          in: query
          description: "For API requests, this value is obtained from parsing the URL.\
          \ For example for `/api/clients` the resulting value is \"clients\". Supported\
          \ operators: `eq`, `ne`, `in`, `contains`."
          schema:
            type: string
          example: login
        - name: "request_method[eq]"
          in: query
          description: "HTTP request method (`GET`, `POST`, `PUT`, etc). Supported operators:\
          \ `eq`, `ne`, `in`."
          schema:
            type: string
            enum:
              - GET
              - POST
              - PUT
              - PATCH
              - DELETE
          example: POST
        - name: "response_code[eq]"
          in: query
          description: "HTTP response code. Supported operators: `eq`, `ne`, `in`, `gt`,\
          \ `gte`, `lt`, `lte`."
          schema:
            type: integer
            format: int64
          example: 200
        - name: "username[eq]"
          in: query
          description: "The user who carried out the action or the name of the API consumer\
          \ (may be empty). Supported operators: `eq`, `ne`, `in`, `contains`."
          schema:
            type: string
          example: johnsmith
        - name: "username[in]"
          in: query
          description: "The user who carried out the action or the name of the API consumer\
          \ (may be empty). Supported operators: `eq`, `ne`, `in`, `contains`."
          schema:
            type: string
          example: "admin1,admin2"
        - name: "client_ip[eq]"
          in: query
          description: "IP address from http request or X_FORWARDED_FOR header if present.\
          \ Supported operators: `eq`, `ne`, `in`."
          schema:
            type: string
          example: 3.73.218.49
        - name: "request_uri[contains]"
          in: query
          description: "The part of the request's URL after the base URL and up to the\
          \ query string. Supported operators: `eq`, `ne`, `in`, `contains`."
          schema:
            type: string
          example: /api/clients
        - name: "request_payload[contains]"
          in: query
          description: "The raw request data as a string, with sensitive information\
          \ removed. For more information, see [Security](/api/pages/audit-trail/security).\
          \ Parameter may be empty. Supported operators: `eq`, `ne`, `in`, `contains`."
          schema:
            type: string
          example: provisionedThroughFederation
        - name: "response_payload[contains]"
          in: query
          description: "The raw response payload with sensitive information removed\
          \ (see details in note below). A response payload is not included with every\
          \ record. Supported operators: `eq`, `ne`, `in`, `contains`."
          schema:
            type: string
          example: SUCCESS
        - name: Host
          in: header
          description: Tenant identifier in Host header
          required: true
          schema:
            type: string
          example: demotenant.mambu.com
      responses:
        "200":
          description: Successfully retrieved events
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuditEventsResponse"
              examples:
                Successful response:
                  description: Successful response
                  value:
                    events:
                      - occurred_at: 2024-01-03T07:04:39.278Z
                        response_code: 200
                        resource: login
                        event_source: UI
                        client_ip: 3.73.218.49
                        request_method: POST
                        request_payload: "{\"username\":[\"johnsmith\"],\"loginType\"\
                        :[\"onlineLogin\"]}"
                        resource_fragment: /servlet/login
                        request_uri: /servlet/login
                        user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
                        response_payload: SUCCESS
                        username: johnsmith
                    totalItemsCount: 10000
                    bytesScanned: 1492285679
                    hasMore: true
                    nextStartTime: 2025-01-04T00:03:13.000Z
        "400":
          description: Invalid request parameters
          content:
            application/json:
              examples:
                Missing time filter:
                  description: Missing time filter
                  value:
                    errors:
                      - message: "occurred_at[gte] or occurred_at[gt] filter is required.\
                        \ occurred_at[lte] or occurred_at[lt] filter is required."
                    status: 400
                Time range too large:
                  description: Time range too large
                  value:
                    errors:
                      - message: The maximum allowed time range is 30 days.
                    status: 400
                Limit exceeded:
                  description: Limit exceeded
                  value:
                    errors:
                      - message: Limit exceed. The maximum allowed limit is 50000.
                    status: 400
                Invalid date value:
                  description: Invalid date value
                  value:
                    errors:
                      - message: Invalid value <invalid value> for occurred_at field.
                          Must be a valid date in ISO8601 standard.
                    status: 400
                Incorrect filter provided:
                  description: Incorrect filter provided
                  value:
                    errors:
                      - message: "Invalid filter occurred_at, must use LHR brackets\
                        \ with an operator syntax"
                    status: 400
        "429":
          description: Rate limit exceeded (1 request per second per tenant)
          content:
            application/json:
              example:
                message: "Throttling: API request limit exceeded"
        "500":
          description: Query execution failed
  /v2/events/metadata:
    get:
      tags:
        - Metadata
      summary: Get search metadata for tenant
      description: |
        Retrieves metadata including the total number of bytes scanned by all audit event queries for the tenant.

        **Important Notes:**
        - Metadata is cached and updated in 15-minute intervals
        - If you search at 15:46:00 UTC, metadata updates at 16:02:00
        - If you search at 16:14:00 UTC, metadata updates at 16:17:00
        - Helps track quota usage against your Audit Trail tier limits

        **Use Case:**
        Track your bytesScanned usage to monitor quota consumption and optimize queries.
      operationId: fetchMetadata
      parameters:
        - name: Host
          in: header
          description: Tenant identifier in Host header
          required: true
          schema:
            type: string
          example: demotenant.mambu.com
      responses:
        "200":
          description: Successfully retrieved metadata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MetadataResponse"
              examples:
                Successful response:
                  description: Successful response
                  value:
                    tenantId: demotenant
                    bytesScanned: 108301221
        "400":
          description: Invalid Host header
          content:
            application/json:
              example:
                errors:
                  - message: Invalid Host header
                status: 400
        "404":
          description: Tenant does not contain information
          content:
            application/json:
              example:
                message: Tenant demotenant does not contain information
components:
  schemas:
    AuditEventsResponse:
      type: object
      properties:
        events:
          type: array
          items:
            type: object
            additionalProperties:
              type: object
        totalItemsCount:
          type: integer
          format: int64
        bytesScanned:
          type: integer
          format: int64
        hasMore:
          type: boolean
        nextStartTime:
          type: string
    MetadataResponse:
      required:
        - bytesScanned
        - tenantId
      type: object
      properties:
        tenantId:
          type: string
          description: Tenant identifier
          example: demotenant
        bytesScanned:
          type: integer
          description: Total number of bytes scanned by all queries
          format: int64
          example: 108301221
      description: Metadata response containing tenant information and bytes scanned
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      description: API key from an API Consumer with MANAGE_AUDIT_TRAIL permission
      name: apikey
      in: header
