> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neuronsearchlab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Submit events

> Submit user interaction events.

## Description

Records user behavior that powers personalization, attribution, analytics, and model training. Events use a `type` field plus a type-specific object so new event shapes can be added without changing shared fields.

Common event types are `impression`, `view`, `click`, `like`, `purchase`, and `conversion`. Your console event definitions decide which types are valid for your tenant.

## Request

```http theme={null}
POST /v1/events
```

```json theme={null}
{
  "user_id": "user-abc123",
  "item_id": "7f3a2c9e",
  "context_id": "101",
  "type": "purchase",
  "occurred_at": 1777478400,
  "purchase": {
    "amount": 4999,
    "currency": "usd"
  },
  "metadata": {
    "surface": "home_feed"
  }
}
```

| Field         | Type    | Required | Description                                                                                                                                      |
| ------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `user_id`     | string  | yes      | End-user identifier.                                                                                                                             |
| `item_id`     | string  | yes      | Item ID such as `7f3a2c9e`.                                                                                                                      |
| `context_id`  | string  | no       | Optional context identifier for analytics and attribution. Use the same context ID convention as your recommendation request, for example `101`. |
| `type`        | string  | yes      | Event type configured in the console.                                                                                                            |
| `session_id`  | string  | no       | Session identifier for attribution and analytics.                                                                                                |
| `request_id`  | string  | no       | Recommendation request ID returned by `GET /v1/recommendations`.                                                                                 |
| `placement`   | string  | no       | Surface or placement where the event occurred.                                                                                                   |
| `occurred_at` | integer | no       | Unix timestamp for when the action happened. Defaults to ingestion time.                                                                         |
| `<type>`      | object  | no       | Type-specific payload. Include `{}` when there are no type-specific fields.                                                                      |
| `metadata`    | object  | no       | Additional event context.                                                                                                                        |

Legacy aliases `userId`, `itemId`, `eventType`, `event_type`, `eventId`, `event_id`, `contextId`, `sessionId`, `requestId`, `client_ts`, `clientTs`, `occurredAt`, and `timestamp` are still accepted. Event batches are capped at 200 events per request by default.

## Response

```json theme={null}
{
  "object": "list",
  "data": [
    {
      "id": "12345",
      "object": "event",
      "user_id": "user-abc123",
      "item_id": "7f3a2c9e",
      "type": "purchase",
      "purchase": {
        "amount": 4999,
        "currency": "usd"
      },
      "session_id": null,
      "request_id": null,
      "context_id": "101",
      "placement": null,
      "metadata": {
        "surface": "home_feed",
        "context_id": "101",
        "purchase": {
          "amount": 4999,
          "currency": "usd"
        }
      },
      "occurred_at": 1777478400,
      "created": 1777478405
    }
  ],
  "has_more": false,
  "url": "/v1/events",
  "inserted": 1,
  "processed": 1,
  "session": {
    "with_session_id": 0,
    "with_request_id": 0
  },
  "embedding_refresh": {
    "users_in_batch": 1,
    "enqueued": true,
    "mode": "async",
    "min_seconds": 30
  }
}
```

The response also returns ingestion stats (`inserted`, `processed`, `session`) and an `embedding_refresh` block describing the async user-embedding refresh job that was enqueued for the affected users.

## Errors

| Status | Scenario                                                                   |
| ------ | -------------------------------------------------------------------------- |
| `400`  | Missing required fields, invalid JSON, unknown item, or unknown event type |
| `401`  | Missing or invalid Bearer token                                            |
| `403`  | Token does not include `neuronsearchlab-api/write`                         |


## OpenAPI

````yaml POST /v1/events
openapi: 3.0.3
info:
  title: NeuronSearchLab Core API
  version: 1.0.0
  description: >-
    Versioned data-plane API for OAuth token exchange, catalog item ingestion,
    user event ingestion, and recommendation serving.
  license:
    name: Proprietary
    url: https://neuronsearchlab.com
servers:
  - url: https://api.neuronsearchlab.com
    description: Core API Gateway custom domain
security:
  - oauth2: []
tags:
  - name: Authentication
    description: OAuth 2.0 client credentials token exchange.
  - name: Items
    description: Catalog item ingestion, lookup, update, deletion, and pagination.
  - name: Events
    description: User interaction event ingestion, lookup, and pagination.
  - name: Recommendations
    description: >-
      Personalized recommendation serving, request-scoped filtering, and
      auto-section generation.
  - name: Search
    description: Query-driven search serving through the Core API data plane.
  - name: CORS
    description: Browser preflight routes generated by API Gateway.
paths:
  /v1/events:
    post:
      tags:
        - Events
      summary: Submit events
      description: >-
        Submit one or more user interaction events. The API accepts snake_case
        and camelCase aliases for common fields. The event type is
        tenant-configured and can be provided as `type`, `event_type`,
        `eventType`, `event_id`, or `eventId`.
      operationId: submitEvents
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EventCreatePayload'
            examples:
              single:
                $ref: '#/components/examples/EventCreate'
              bulk:
                $ref: '#/components/examples/EventCreateBulk'
      responses:
        '200':
          description: Inserted events
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventIngestResult'
              examples:
                ingested:
                  $ref: '#/components/examples/EventIngestResult'
        '400':
          $ref: '#/components/responses/Error400'
        '401':
          $ref: '#/components/responses/Error401'
        '403':
          $ref: '#/components/responses/Error403'
        '500':
          $ref: '#/components/responses/Error500'
      security:
        - oauth2:
            - neuronsearchlab-api/write
components:
  schemas:
    EventCreatePayload:
      oneOf:
        - $ref: '#/components/schemas/EventCreate'
        - type: array
          items:
            $ref: '#/components/schemas/EventCreate'
          minItems: 1
          maxItems: 200
    EventIngestResult:
      allOf:
        - $ref: '#/components/schemas/EventList'
        - type: object
          required:
            - inserted
            - processed
            - session
            - embedding_refresh
          properties:
            inserted:
              type: integer
              minimum: 0
            processed:
              type: integer
              minimum: 0
            session:
              type: object
              required:
                - with_session_id
                - with_request_id
              properties:
                with_session_id:
                  type: integer
                  minimum: 0
                with_request_id:
                  type: integer
                  minimum: 0
            embedding_refresh:
              type: object
              required:
                - users_in_batch
                - enqueued
                - mode
                - min_seconds
              properties:
                users_in_batch:
                  type: integer
                  minimum: 0
                enqueued:
                  type: boolean
                mode:
                  type: string
                  enum:
                    - async
                min_seconds:
                  type: integer
                  minimum: 0
    EventCreate:
      type: object
      description: >-
        At least one user ID alias, one item ID alias, and one event type alias
        are required. Type-specific payloads are accepted as additional object
        properties named after the event type.
      properties:
        user_id:
          type: string
          description: End-user identifier.
          example: user-abc123
        userId:
          type: string
          description: CamelCase alias for `user_id`.
        item_id:
          type: string
          description: Public item ID.
          pattern: ^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$
          example: 7f3a2c9e
        itemId:
          type: string
          description: CamelCase alias for `item_id`.
          pattern: ^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$
        type:
          type: string
          description: Tenant-configured event type.
          example: purchase
        event_type:
          type: string
          description: Snake-case alias for `type`.
        eventType:
          type: string
          description: CamelCase alias for `type`.
        event_id:
          oneOf:
            - type: string
            - type: number
          description: Legacy alias for event type.
        eventId:
          oneOf:
            - type: string
            - type: number
          description: CamelCase legacy alias for event type.
        session_id:
          type: string
          description: Optional session identifier.
        sessionId:
          type: string
          description: CamelCase alias for `session_id`.
        request_id:
          type: string
          format: uuid
          description: Recommendation request ID to attribute this event to.
        requestId:
          type: string
          format: uuid
          description: CamelCase alias for `request_id`.
        context_id:
          type: string
          description: >-
            Optional context identifier for analytics and attribution. Use the
            same context ID convention as the recommendation request.
          example: '101'
        contextId:
          type: string
          description: CamelCase alias for context_id.
          example: '101'
        placement:
          type: string
          description: Surface or placement where the event happened.
          example: home_feed
        metadata:
          $ref: '#/components/schemas/Metadata'
        occurred_at:
          oneOf:
            - type: integer
              format: int64
            - type: string
              format: date-time
          description: >-
            Event occurrence timestamp. Numeric values below 1e12 are
            interpreted as Unix seconds.
          example: 1777478400
        occurredAt:
          description: CamelCase alias for `occurred_at`.
          oneOf:
            - type: integer
              format: int64
            - type: string
              format: date-time
        timestamp:
          description: Legacy timestamp alias.
          oneOf:
            - type: integer
              format: int64
            - type: string
              format: date-time
        client_ts:
          description: Legacy client timestamp alias.
          oneOf:
            - type: integer
              format: int64
            - type: string
              format: date-time
        clientTs:
          description: CamelCase alias for `client_ts`.
          oneOf:
            - type: integer
              format: int64
            - type: string
              format: date-time
      additionalProperties: true
      example:
        user_id: user-abc123
        item_id: 7f3a2c9e
        context_id: '101'
        type: purchase
        occurred_at: 1777478400
        purchase:
          amount: 4999
          currency: usd
        metadata:
          surface: home_feed
    EventList:
      allOf:
        - $ref: '#/components/schemas/ListEnvelope'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Event'
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - code
            - message
          properties:
            type:
              type: string
              enum:
                - invalid_request_error
                - authentication_error
                - permission_error
                - not_found_error
                - conflict_error
                - rate_limit_error
                - api_error
            code:
              type: string
            message:
              type: string
            details: {}
            request_id:
              type: string
              format: uuid
          additionalProperties: true
    Metadata:
      type: object
      description: Arbitrary JSON object used for filtering, ranking, and debugging.
      additionalProperties: true
      example:
        category: electronics
        brand: Acme
        price: 10999
        currency: usd
    ListEnvelope:
      type: object
      required:
        - object
        - data
        - has_more
        - url
      properties:
        object:
          type: string
          enum:
            - list
        data:
          type: array
          items: {}
        has_more:
          type: boolean
        next_cursor:
          type: string
          nullable: true
        url:
          type: string
    Event:
      type: object
      required:
        - id
        - object
        - user_id
        - item_id
        - type
        - metadata
        - occurred_at
        - created
      properties:
        id:
          type: string
          pattern: ^[1-9][0-9]*$
          example: '12345'
        object:
          type: string
          enum:
            - event
        user_id:
          type: string
          example: user-abc123
        item_id:
          type: string
          example: 7f3a2c9e
        type:
          type: string
          example: purchase
        session_id:
          type: string
          nullable: true
        request_id:
          type: string
          format: uuid
          nullable: true
        context_id:
          type: string
          nullable: true
          example: '101'
        placement:
          type: string
          nullable: true
          example: home_feed
        metadata:
          $ref: '#/components/schemas/Metadata'
        occurred_at:
          type: integer
          format: int64
          nullable: true
          example: 1777478400
        created:
          type: integer
          format: int64
          nullable: true
          example: 1777478405
      additionalProperties: true
  examples:
    EventCreate:
      summary: Submit one event
      value:
        user_id: user-abc123
        item_id: 7f3a2c9e
        context_id: '101'
        type: purchase
        request_id: c7f0d2bb-56b1-4ca7-8f09-84d8e4ed02b4
        occurred_at: 1777478400
        purchase:
          amount: 4999
          currency: usd
        metadata:
          surface: home_feed
    EventCreateBulk:
      summary: Submit multiple events
      value:
        - user_id: user-abc123
          item_id: 7f3a2c9e
          type: view
          occurred_at: 1777478400
        - user_id: user-abc123
          item_id: 7f3a2c9e
          type: purchase
          purchase:
            amount: 4999
            currency: usd
    EventIngestResult:
      summary: Inserted events
      value:
        object: list
        data:
          - id: '12345'
            object: event
            user_id: user-abc123
            item_id: 7f3a2c9e
            type: purchase
            purchase:
              amount: 4999
              currency: usd
            session_id: null
            request_id: null
            context_id: '101'
            placement: null
            metadata:
              surface: home_feed
              context_id: '101'
              purchase:
                amount: 4999
                currency: usd
            occurred_at: 1777478400
            created: 1777478405
        has_more: false
        url: /v1/events
        inserted: 1
        processed: 1
        session:
          with_session_id: 0
          with_request_id: 0
        embedding_refresh:
          users_in_batch: 1
          enqueued: true
          mode: async
          min_seconds: 30
    ErrorValidation:
      summary: Validation error
      value:
        error:
          type: invalid_request_error
          code: validation_error
          message: Validation error
          details:
            fieldErrors:
              name:
                - Required
    ErrorUnauthorized:
      summary: Unauthorized
      value:
        error:
          type: authentication_error
          code: unauthorized_no_client_id_in_jwt
          message: 'Unauthorized: No client ID in JWT'
  responses:
    Error400:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            validation:
              $ref: '#/components/examples/ErrorValidation'
    Error401:
      description: Unauthenticated
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            unauthorized:
              $ref: '#/components/examples/ErrorUnauthorized'
    Error403:
      description: Forbidden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Error500:
      description: Server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    oauth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth.neuronsearchlab.com/oauth2/token
          scopes:
            neuronsearchlab-api/read: Read recommendations, items, and events.
            neuronsearchlab-api/write: Create, update, and delete items; submit events.

````