Ninetailed Events API

Batch event ingestion endpoints for profile enrichment.

OpenAPI Specification

ninetailed-events-api-openapi.yml Raw ↑
openapi: 3.0.1
info:
  title: Ninetailed Experience Events API
  description: The core REST API for the Ninetailed (now Contentful Personalization) platform. Returns visitor profiles and resolves which experience and variant to render based on audience rules. Deployed on the edge for high performance. Supports profile creation, updates, retrieval, deletion, event tracking, and batch event import for audience segmentation and A/B test delivery.
  version: '2'
  contact:
    name: Ninetailed Support
    url: https://www.contentful.com/help/
  license:
    name: Proprietary
servers:
- url: https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}
  description: Ninetailed Experience API edge endpoint
  variables:
    organizationId:
      description: The organization ID (Client ID) found in the SDK Keys section on the Optimization tab.
      default: YOUR_ORGANIZATION_ID
    environmentSlug:
      description: The environment slug (e.g. "main").
      default: main
tags:
- name: Events
  description: Batch event ingestion endpoints for profile enrichment.
paths:
  /events:
    post:
      operationId: batchUpsertSync
      summary: Batch Upsert Events (Synchronous)
      description: Synchronous batch endpoint for upserting events across multiple profiles. Supports up to 200 events total, a maximum of 50 identify events, and up to 50 unique profiles per request. Returns an array of profiles without experiences or changes.
      tags:
      - Events
      parameters:
      - $ref: '#/components/parameters/locale'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchEventsRequest'
            example:
              events:
              - type: identify
                userId: user-abc
                traits:
                  plan: enterprise
              - type: page
                userId: user-abc
                properties:
                  url: https://example.com/pricing
                  path: /pricing
          text/plain:
            schema:
              $ref: '#/components/schemas/BatchEventsRequest'
      responses:
        '200':
          description: Events processed; returns array of updated profiles.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchEventsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /import/events:
    post:
      operationId: batchUpsertAsync
      summary: Batch Upsert Events (Asynchronous)
      description: Asynchronous fire-and-forget batch endpoint for importing events. Returns 200 immediately without waiting for processing. Ideal for high-volume imports where response data is not needed.
      tags:
      - Events
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchEventsRequest'
          text/plain:
            schema:
              $ref: '#/components/schemas/BatchEventsRequest'
      responses:
        '200':
          description: Request accepted for asynchronous processing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AsyncConfirmation'
        '400':
          $ref: '#/components/responses/BadRequest'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  parameters:
    locale:
      name: locale
      in: query
      required: false
      description: BCP 47 locale string used for resolving localized experiences. Defaults to "en".
      schema:
        type: string
        default: en
        example: en-US
  schemas:
    Session:
      type: object
      description: Session-level metadata for the visitor.
      properties:
        id:
          type: string
          description: Unique session identifier.
        isReturningVisitor:
          type: boolean
          description: True if the visitor has been seen in a previous session.
        landingPage:
          type: string
          description: URL of the first page visited in this session.
        count:
          type: integer
          description: Number of sessions this visitor has had.
        sessionLength:
          type: integer
          description: Length of the current session in seconds.
    Location:
      type: object
      description: Geographic location resolved from the visitor's IP address.
      properties:
        lat:
          type: number
          format: double
          description: Latitude coordinate.
        lon:
          type: number
          format: double
          description: Longitude coordinate.
        city:
          type: string
          description: City name.
        region:
          type: string
          description: Region or state code.
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code.
        timezone:
          type: string
          description: IANA timezone identifier (e.g. "America/New_York").
    AsyncConfirmation:
      type: object
      description: Confirmation that an asynchronous import request was accepted.
      properties:
        data:
          type: object
          description: Empty object; processing happens asynchronously.
        error:
          type: object
          nullable: true
        message:
          type: string
          example: ok
    BatchEventsResponse:
      type: object
      description: Response envelope for synchronous batch events, containing profile updates without experiences.
      properties:
        data:
          type: array
          description: Array of updated profiles.
          items:
            $ref: '#/components/schemas/Profile'
        error:
          type: object
          nullable: true
        message:
          type: string
          example: ok
    Profile:
      type: object
      description: A visitor profile containing identity, behavioral, and session data used for personalization.
      properties:
        id:
          type: string
          description: Unique identifier for the visitor profile.
        stableId:
          type: string
          description: Stable cross-session identifier for the visitor.
        random:
          type: number
          format: double
          minimum: 0
          maximum: 1
          description: Random value (0-1) used for traffic splitting in A/B tests.
        audiences:
          type: array
          description: List of audience IDs the visitor currently qualifies for.
          items:
            type: string
        traits:
          type: object
          additionalProperties: true
          description: Merged identify traits for the visitor.
        location:
          $ref: '#/components/schemas/Location'
        session:
          $ref: '#/components/schemas/Session'
        jurisdiction:
          type: string
          description: Regulatory jurisdiction code (e.g. "GDPR") resolved from location.
        stickyVariants:
          type: object
          additionalProperties:
            type: string
          description: Map of experience ID to variant index for sticky (consistent) assignment.
    BatchEventsRequest:
      type: object
      required:
      - events
      description: Request body for batch event ingestion. Maximum 200 events, 50 identify events, 50 unique profiles per request.
      properties:
        events:
          type: array
          maxItems: 200
          description: Array of events to ingest across multiple profiles.
          items:
            $ref: '#/components/schemas/Event'
    ApiError:
      type: object
      description: Error response envelope.
      required:
      - message
      - error
      properties:
        message:
          type: string
          description: Human-readable error message.
        data:
          type: object
          description: Empty object on error.
        error:
          type: object
          description: Structured error details.
          properties:
            code:
              type: string
              enum:
              - ERR_INVALID_DATA
              - ERR_CONFIG_NOT_FOUND
              - ERR_PROFILE_NOT_FOUND
              - ERR_NAMESPACE_MISMATCH
              - ERR_PROFILE_OVERLOAD
              - ERR_INTERNAL_SERVER_ERROR
              description: Machine-readable error code.
    Event:
      type: object
      required:
      - type
      description: A behavioral or identity event associated with a visitor profile.
      properties:
        type:
          type: string
          enum:
          - page
          - track
          - identify
          - screen
          - component
          description: The type of event being recorded.
        userId:
          type: string
          description: Stable user identifier for linking anonymous and identified sessions.
        anonymousId:
          type: string
          description: Anonymous identifier for unidentified visitors.
        name:
          type: string
          description: Name of the page, screen, or track event.
        traits:
          type: object
          additionalProperties: true
          description: Key-value pairs describing user attributes (used with identify events).
        properties:
          type: object
          additionalProperties: true
          description: Key-value pairs describing event properties (used with page/track events).
          properties:
            url:
              type: string
              format: uri
              description: Full URL of the page.
            path:
              type: string
              description: Path portion of the URL.
            title:
              type: string
              description: Page title.
            referrer:
              type: string
              format: uri
              description: Referring URL.
        timestamp:
          type: string
          format: date-time
          description: ISO 8601 timestamp of when the event occurred.
  responses:
    BadRequest:
      description: Invalid request data.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            message: Invalid data provided
            data: {}
            error:
              code: ERR_INVALID_DATA
    TooManyRequests:
      description: Profile has exceeded the allowed number of concurrent requests.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            message: Profile overload
            data: {}
            error:
              code: ERR_PROFILE_OVERLOAD
    InternalServerError:
      description: An unexpected server error occurred.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
          example:
            message: Internal server error
            data: {}
            error:
              code: ERR_INTERNAL_SERVER_ERROR