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

# Track Event

> Track a user event with metadata for semantic clustering and journey tracking

## Overview

The `/track` endpoint is the core of Turret's API. Use it to send user events with metadata for automatic semantic clustering and journey tracking.

## Request Body

<ParamField body="name" type="string" required>
  Event name (e.g., "user\_message", "search\_query"). Used to categorize events.
</ParamField>

<ParamField body="session_id" type="string">
  Your conversation/thread ID. Critical for journey tracking. **Auto-generated if not provided.** Include the returned `session_id` in subsequent messages to connect them into a conversation.
</ParamField>

<ParamField body="user_id" type="string">
  Your user's ID. Enables cross-session analysis. **Auto-generated if not provided.** Store and reuse to track the same user across conversations.
</ParamField>

<ParamField body="metadata" type="object" required>
  Object containing the data to cluster. The key (e.g., "prompt") becomes the clustering dimension. The value is the text that gets semantically clustered.
</ParamField>

## Example Request

### First Message (IDs Auto-Generated)

```bash theme={null}
curl -X POST https://api.useturret.com/track \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "user_message",
    "metadata": {
      "prompt": "How do I reset my password?"
    }
  }'
```

### Subsequent Messages (Include IDs)

```bash theme={null}
curl -X POST https://api.useturret.com/track \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "user_message",
    "session_id": "6fa459ea-ee8a-3ca4-894e-db77e160355e",
    "user_id": "550e8400-e29b-41d4-a716-446655440000",
    "metadata": {
      "prompt": "Thanks! How do I change my email?"
    }
  }'
```

## Response

<ResponseField name="session_id" type="string">
  The session ID for this event. Either your provided ID or an auto-generated UUID. **Store this and include it in subsequent messages** to connect them into a conversation journey.
</ResponseField>

<ResponseField name="user_id" type="string">
  The user ID for this event. Either your provided ID or an auto-generated UUID. Store this to track the same user across conversations.
</ResponseField>

## Example Response

```json theme={null}
{
  "session_id": "6fa459ea-ee8a-3ca4-894e-db77e160355e",
  "user_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

<Warning>
  **Important:** Store the returned `session_id` and include it in all subsequent messages within the same conversation. Without this, Turret cannot track the user's journey through topics.
</Warning>

## How It Works

1. **Event Ingestion**: When you POST an event, Turret stores it with its metadata.

2. **Embedding Generation**: Turret generates a vector embedding for the metadata value (e.g., the prompt text) using an embedding model.

3. **Semantic Clustering**: Events are grouped into clusters based on embedding similarity. Similar prompts end up in the same cluster, even if they use different words:
   * "How do I reset my password?" and "I forgot my login credentials" → Same cluster

4. **Cluster Labeling**: Clusters are automatically labeled with human-readable descriptions using an LLM (e.g., "Password Reset Requests").

5. **Journey Tracking**: When events share the same `session_id`, Turret tracks transitions between clusters:
   * User asks about pricing (Cluster A)
   * User asks about features (Cluster B)
   * User asks about pricing again (Cluster A)
   * This creates a journey: A → B → A

## Common Use Cases

### Track User Messages (Minimal)

```json theme={null}
{
  "name": "user_message",
  "metadata": {
    "prompt": "Write a product description for wireless headphones"
  }
}
```

Response returns `session_id` and `user_id` - store these for subsequent messages.

### Track with Your Own IDs

```json theme={null}
{
  "name": "user_message",
  "session_id": "your-conversation-id",
  "user_id": "your-user-id",
  "metadata": {
    "prompt": "How do I export my data?"
  }
}
```

### Track Search Queries

```json theme={null}
{
  "name": "search_query",
  "metadata": {
    "query": "best coffee shops near me"
  }
}
```

### Track with Additional Context

```json theme={null}
{
  "name": "user_message",
  "session_id": "thread_xyz",
  "metadata": {
    "prompt": "How do I export my data?",
    "detected_language": "english",
    "platform": "mobile"
  }
}
```

## Error Responses

### Invalid API Key (401)

```json theme={null}
{
  "success": false,
  "error": "Invalid API key",
  "code": "INVALID_API_KEY"
}
```

### Missing Required Fields (400)

```json theme={null}
{
  "success": false,
  "error": "Missing required field: name",
  "code": "MISSING_REQUIRED_FIELD"
}
```

### Rate Limit Exceeded (429)

```json theme={null}
{
  "success": false,
  "error": "Rate limit exceeded. Try again in 1 hour.",
  "code": "RATE_LIMIT_EXCEEDED",
  "retry_after": 3600
}
```

## Best Practices

### Session ID Management

* **First message:** Omit `session_id` - Turret generates one
* **Store the response:** Save the returned `session_id`
* **Subsequent messages:** Always include the stored `session_id`
* **New conversation:** Omit `session_id` again to start fresh

### Using Your Own IDs

If you already have conversation IDs (most apps do):

* Pass your conversation ID as `session_id`
* Pass your user ID as `user_id`
* Turret uses your IDs as-is

### Event Names

* Use descriptive names (e.g., "user\_message", "search\_query")
* Keep names consistent across your app
* Avoid generic names like "event" or "action"

### Metadata Structure

* Include the user's actual text in the `prompt` or `query` field
* Keep text fields under 10,000 characters
* Additional metadata fields provide context but aren't clustered

### Error Handling

* Check response status codes
* Implement retry logic with exponential backoff
* Don't let tracking failures break your main application flow

<Tip>
  **Critical for journey tracking:** The `session_id` connects messages into a conversation. Without it, Turret can cluster topics but cannot show how users flow through them.
</Tip>


## OpenAPI

````yaml POST /track
openapi: 3.1.0
info:
  title: Turret API
  description: >-
    A product analytics API designed for AI/LLM applications. It provides
    semantic topic clustering and user journey tracking.
  version: 1.0.0
  contact:
    name: Turret Support
    email: support@useturret.com
servers:
  - url: https://api.useturret.com
    description: Production server
security:
  - apiKey: []
paths:
  /track:
    post:
      summary: Track an event
      description: >-
        Track a user event with metadata for semantic clustering and journey
        tracking
      operationId: trackEvent
      requestBody:
        description: Event data to track
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TrackEventRequest'
            examples:
              basicPrompt:
                summary: Basic prompt tracking
                value:
                  name: user_prompt
                  metadata:
                    prompt: How do I reset my password?
              fullJourneyTracking:
                summary: Full journey tracking (recommended)
                value:
                  name: user_prompt
                  session_id: conv_abc123
                  user_id: user_456
                  metadata:
                    prompt: How do I reset my password?
              searchQuery:
                summary: Search query tracking
                value:
                  name: search_query
                  session_id: session_789
                  user_id: user_456
                  metadata:
                    query: best coffee shops near me
              withContext:
                summary: With additional context
                value:
                  name: chat_message
                  session_id: thread_xyz
                  metadata:
                    prompt: How do I export my data?
                    detected_language: english
      responses:
        '200':
          description: Event successfully tracked
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrackEventResponse'
        '400':
          description: Invalid request format or missing required fields
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitErrorResponse'
components:
  schemas:
    TrackEventRequest:
      type: object
      required:
        - name
        - metadata
      properties:
        name:
          type: string
          description: >-
            Event name (e.g., 'user_prompt', 'search_query'). Used to categorize
            events.
          example: user_prompt
          minLength: 1
          maxLength: 255
        session_id:
          type: string
          description: >-
            Your conversation/thread ID. Critical for journey tracking. Events
            with the same session_id are connected into a user flow.
          example: conv_abc123
        user_id:
          type: string
          description: >-
            Your user's ID. Enables cross-session analysis (tracking the same
            user across multiple conversations).
          example: user_456
        metadata:
          type: object
          description: >-
            Object containing the data to cluster. The key (e.g., 'prompt')
            becomes the clustering dimension. The value is the text that gets
            semantically clustered.
          additionalProperties: true
          example:
            prompt: How do I reset my password?
    TrackEventResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Indicates if the event was successfully tracked
          example: true
        message:
          type: string
          description: Human-readable message about the result
          example: Event tracked successfully
        event_id:
          type: string
          description: Unique identifier for the tracked event
          example: evt_1234567890abcdef
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Always false for error responses
          example: false
        error:
          type: string
          description: Human-readable error message
          example: Invalid API key
        code:
          type: string
          description: Machine-readable error code
          example: INVALID_API_KEY
    RateLimitErrorResponse:
      allOf:
        - $ref: '#/components/schemas/ErrorResponse'
        - type: object
          properties:
            retry_after:
              type: integer
              description: Number of seconds to wait before retrying
              example: 3600
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: Your project API key from the Turret dashboard

````