openapi: '3.1.0'
info:
  title: 'AppEvent API'
  version: 'v1.0.0'
  summary: API to send s2s app events to justtrack
  description: |-

servers:
  - url: https://app-events.justtrack.io

paths:
  /appevents/v1:
    post:
      summary: Send a batch of app events to justtrack
      description: |
        Sends batches of batches of events where each inner batch is for a single app and user.
        Follows a bulk processing paradigm where individual AppEventBatches in the InputBatch are processed
        independently from each other. If an AppEventBatch fails to be processed, this does not affect the processing
        of the other AppEventBatches in the InputBatch. For all AppEventBatches that fail an individual error status is
        set for its batchId for the "207" status code. An individual AppEventBatch is processed "all or nothing".
        After acceptance of a batch, there is delayed processing of it in subsequent components where additional validation happens.
        This means that even though a batch was successfully accepted, not necessarily all events will pass processing.
        This subsequent processing includes but is not limited to:
        - deduplication
        - additional semantic validation
        - user identity resolution
        User Identity is determined once for the whole batch for an app user combination, using the newest information which predates the newest event in the batch.
      operationId: postAppEventBatch
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InputBatch'
        required: true
      responses:
        '200':
          description: OK
        '207':
          description: 'Partial Success. Some events were not processed successfully. Check the response for details.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiErrorResponse'
        '400':
          description: 'Bad Request Input. Check the response for details'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: 'Unauthorized. Please check you authentication details.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: 'Internal Server Error. Please try again or contact us if the error persists'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '502':
          description: 'Bad Gateway while committing the events, please try again after a short backoff.'

security:
  - ApiKeyAuth: []

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

  schemas:
    MultiErrorResponse:
      type: array
      items:
        $ref: '#/components/schemas/BatchErrorResponse'
      example:
        - batchId: 'efe0d8d2-164b-49b8-b0cd-99e0bb4dca56'
          error: 'validation failed'
        - batchId: '7890abcd-164b-49b8-b0cd-99e0bb4dca56'
          error: 'invalid format'
    BatchErrorResponse:
      type: object
      required:
        - batchId
        - statusCode
        - error
      properties:
        batchId:
          $ref: '#/components/schemas/BatchId'
        error:
          $ref: '#/components/schemas/Error'
        statusCode:
          type: integer
          description: The HTTP status code
          example: 400
          x-oapi-codegen-extra-tags:
            binding: required
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
    Error:
      type: string
      minLength: 1
      description: description of the error
      example: 'validation failed'
      x-oapi-codegen-extra-tags:
        binding: min=1
    InputBatch:
      type: array
      description: A batch of AppEvent batches. Follows a bulk processing paradigm where each individual AppEventBatch can fail or succeed independently.
      items:
        $ref: '#/components/schemas/AppEventBatch'
    AppEventBatch:
      type: object
      description: |
        A batch of AppEvents, all for one app user combination. If one event is invalid, the whole batch is rejected.
      required:
        - batchId
        - app
        - user
        - events
      properties:
        batchId:
          $ref: '#/components/schemas/BatchId'
        app:
          $ref: '#/components/schemas/App'
        user:
          $ref: '#/components/schemas/User'
        events:
          type: array
          items:
            $ref: '#/components/schemas/AppEvent'
          x-oapi-codegen-extra-tags:
            binding: required
    BatchId:
      type: string
      format: uuid
      description: 36 character uuid of the batch
      minLength: 36
      maxLength: 36
      example: 'efe0d8d2-164b-49b8-b0cd-99e0bb4dca56'
      x-oapi-codegen-extra-tags:
        binding: required,uuid4
    App:
      type: object
      required:
        - storeId
      properties:
        version:
          $ref: '#/components/schemas/AppVersion'
        storeId:
          type: string
          minLength: 1
          maxLength: 255
          description: The store id of the app
          x-oapi-codegen-extra-tags:
            binding: required,min=1,max=255
    AppVersion:
      type: object
      required:
        - code
        - name
      properties:
        code:
          type: string
          description: Increasing number on android, major.minor on iOS
          x-oapi-codegen-extra-tags:
            binding: required,min=1
        name:
          type: string
          description: The name of the app version
          x-oapi-codegen-extra-tags:
            binding: required,min=1
    User:
      type: object
      anyOf:
        - required: [id]
        - required: [installInstanceId]
        - required: [attributionId]
        - required: [deviceId]
      properties:
        id:
          type: string
          description: id of the user, that was provided to the justtrack sdk through SetUserId. It is NOT the legacy justtrack user id.
          minLength: 1
          x-oapi-codegen-extra-tags:
            binding: omitempty,min=1
        installInstanceId:
          type: string
          format: uuid
          description: 36 character uuid of the installation. Does not change across reinstalls as part of retargeting. Can be retrieved from the justtrack sdk by calling getInstallInstanceId.
          minLength: 36
          maxLength: 36
          x-oapi-codegen-extra-tags:
            binding: omitempty,uuid4
        attributionId:
          type: string
          format: uuid
          description: 36 character uuid of the attribution of the user.
          minLength: 36
          maxLength: 36
          x-oapi-codegen-extra-tags:
            binding: omitempty,uuid4
        deviceId:
          type: string
          description: GAID or IDFA, depending on platform
          x-oapi-codegen-extra-tags:
            binding: omitempty,min=36
      x-oapi-codegen-extra-tags:
        binding: required
    AppEvent:
      type: object
      oneOf:
        - required:
            - unit
        - required:
            - currency
      required:
        - id
        - event
        - dimensions
        - value
        - happenedAt
      properties:
        unit:
          type: string
          description: Specifies the unit represented by the value field. **Mutually exclusive with currency.**
          enum:
            - count
            - seconds
            - milliseconds
            - ''
          x-oapi-codegen-extra-tags:
            binding: omitempty,oneof=count seconds milliseconds
        currency:
          type: string
          description: ISO 4217 currency for the value field. **Mutually exclusive with unit.**
          minLength: 3
          maxLength: 3
          examples:
            - USD
            - EUR
          x-oapi-codegen-extra-tags:
            binding: omitempty,len=3,iso4217
        id:
          type: string
          format: uuid
          description: Globally unique id of the event.
          minLength: 36
          maxLength: 36
          x-oapi-codegen-extra-tags:
            binding: required,uuid4
        event:
          type: string
          description: name of the event, e.g. level_success.
          minLength: 1
          examples:
            - adjoe_iap_revenue
            - adjoe_retention_d7
          x-oapi-codegen-extra-tags:
            binding: required,min=1
        dimensions:
          type: object
          description: additional information about the event. Can contain any key for dimensions.
          additionalProperties:
            type: string
          examples:
            - jt_ad_bundle_id: com.facebook.Facebook
          x-oapi-codegen-extra-tags:
            binding: required
        value:
          type: number
          format: double
          description: |
            Specifies the numerical value for the set unit/currency, eg 1004 milliseconds, 1 count, or 5.99 USD.
            If both Unit and Currency are not set, value is always set to 0.
          examples:
            - 1004
            - 1.00
            - 5.99
          x-oapi-codegen-extra-tags:
            binding: omitempty
        countryCode:
          type: string
          description: ISO 3166-1 alpha-2 country code of where the event happened
          minLength: 2
          maxLength: 2
          example: US
          x-oapi-codegen-extra-tags:
            binding: omitempty,iso3166_1_alpha2
        happenedAt:
          type: string
          format: date-time
          description: when did the event happen?
          x-oapi-codegen-extra-tags:
            binding: required,datetime=2006-01-02T15:04:05.999Z07:00
