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

# Data Model

> Understanding the Event object - the atomic unit of agent observability

## Overview

The `Event` object is the fundamental building block of Fabraix's observability system. Every action, decision, and interaction in your agent's lifecycle is captured as an Event.

## Event Structure

The Event object has a precise structure designed for flexibility and comprehensive tracking:

```typescript theme={null}
interface Event {
  id: string;           // Unique identifier (UUID)
  timestamp: datetime;  // ISO 8601 timestamp
  trace_id: string;     // Session identifier
  type: EventType;      // Event category
  content: string;      // Stringified JSON payload
  schema: string;       // JSON Schema definition
}
```

## Field Definitions

<ParamField path="id" type="string" required>
  A unique identifier for the event (typically a UUID). This ID is generated by your system and should be globally unique.

  **Example**: `"e7d4f3a2-8b1c-4d9e-a5f6-2c3d4e5f6a7b"`
</ParamField>

<ParamField path="timestamp" type="datetime" required>
  The precise time when the event occurred, formatted as ISO 8601.

  **Format**: `YYYY-MM-DDTHH:mm:ss.sssZ`

  **Example**: `"2024-01-15T14:30:45.123Z"`
</ParamField>

<ParamField path="trace_id" type="string" required>
  The unique session identifier returned from `/register-agent-run`. This links the event to a specific agent session.

  **Example**: `"f4f4f4f4-f4f4-f4f4-f4f4-f4f4f4f4f4f4"`
</ParamField>

<ParamField path="type" type="enum" required>
  The logical category of the event. Must be one of:

  * `user` - Human user input
  * `model_input` - Data sent to LLM
  * `model_output` - LLM responses
  * `system` - System-level events
  * `tool` - Tool/function calls
  * `environment` - External system data
  * `memory` - Memory operations
  * `error` - Error conditions
</ParamField>

<ParamField path="content" type="string" required>
  The actual event data as a stringified JSON object. This must validate against the provided schema.

  **Example**:

  ```json theme={null}
  "{\"location\":\"London, UK\",\"units\":\"celsius\"}"
  ```
</ParamField>

<ParamField path="schema" type="string" required>
  A stringified JSON Schema that defines the structure of the content field. This enables dynamic validation and understanding of diverse event types.

  **Example**:

  ```json theme={null}
  "{\"type\":\"object\",\"properties\":{\"location\":{\"type\":\"string\"},\"units\":{\"type\":\"string\"}}}"
  ```
</ParamField>

## Content and Schema Relationship

The power of Fabraix's data model lies in the relationship between `content` and `schema`. The schema defines what the content should look like, enabling:

* **Dynamic Validation**: Content is validated against its schema
* **Type Safety**: Clear contracts for event data
* **Flexibility**: Support for any data structure
* **Documentation**: Self-describing events

### Example: Tool Event

Here's how content and schema work together for a tool call:

<CodeGroup>
  ```python Python theme={null}
  # The schema defines the tool's signature
  tool_schema = {
      "type": "function",
      "name": "search_database",
      "description": "Search the customer database",
      "parameters": {
          "type": "object",
          "properties": {
              "query": {
                  "type": "string",
                  "description": "Search query"
              },
              "filters": {
                  "type": "object",
                  "properties": {
                      "status": {
                          "type": "string",
                          "enum": ["active", "inactive", "pending"]
                      },
                      "created_after": {
                          "type": "string",
                          "format": "date-time"
                      }
                  }
              },
              "limit": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 100,
                  "default": 10
              }
          },
          "required": ["query"]
      }
  }

  # The content contains the actual arguments
  tool_content = {
      "query": "enterprise customers",
      "filters": {
          "status": "active",
          "created_after": "2024-01-01T00:00:00Z"
      },
      "limit": 25
  }

  # Submit the event
  log_event(
      trace_id=trace_id,
      event_type="tool",
      content=json.dumps(tool_content),
      schema=json.dumps(tool_schema)
  )
  ```

  ```javascript JavaScript theme={null}
  // The schema defines the tool's signature
  const toolSchema = {
    type: "function",
    name: "search_database",
    description: "Search the customer database",
    parameters: {
      type: "object",
      properties: {
        query: {
          type: "string",
          description: "Search query"
        },
        filters: {
          type: "object",
          properties: {
            status: {
              type: "string",
              enum: ["active", "inactive", "pending"]
            },
            created_after: {
              type: "string",
              format: "date-time"
            }
          }
        },
        limit: {
          type: "integer",
          minimum: 1,
          maximum: 100,
          default: 10
        }
      },
      required: ["query"]
    }
  };

  // The content contains the actual arguments
  const toolContent = {
    query: "enterprise customers",
    filters: {
      status: "active",
      created_after: "2024-01-01T00:00:00Z"
    },
    limit: 25
  };

  // Submit the event
  await logEvent(
    traceId,
    "tool",
    JSON.stringify(toolContent),
    JSON.stringify(toolSchema)
  );
  ```
</CodeGroup>

## Event Type Examples

### User Event

Captures input from human users:

```json theme={null}
{
  "type": "user",
  "content": "{\"message\":\"What's the weather in Paris?\",\"user_id\":\"user-123\"}",
  "schema": "{\"type\":\"object\",\"properties\":{\"message\":{\"type\":\"string\"},\"user_id\":{\"type\":\"string\"}}}"
}
```

### Model Input Event

Data sent to the LLM:

```json theme={null}
{
  "type": "model_input",
  "content": "{\"messages\":[{\"role\":\"system\",\"content\":\"You are helpful\"},{\"role\":\"user\",\"content\":\"What's 2+2?\"}],\"temperature\":0.7}",
  "schema": "{\"type\":\"object\",\"properties\":{\"messages\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"temperature\":{\"type\":\"number\"}}}"
}
```

### Model Output Event

LLM responses:

```json theme={null}
{
  "type": "model_output",
  "content": "{\"response\":\"2+2 equals 4\",\"confidence\":0.99,\"tokens_used\":15}",
  "schema": "{\"type\":\"object\",\"properties\":{\"response\":{\"type\":\"string\"},\"confidence\":{\"type\":\"number\"},\"tokens_used\":{\"type\":\"integer\"}}}"
}
```

### Memory Event

Memory operations:

```json theme={null}
{
  "type": "memory",
  "content": "{\"operation\":\"write\",\"key\":\"user_preferences\",\"value\":{\"language\":\"en\",\"timezone\":\"EST\"}}",
  "schema": "{\"type\":\"object\",\"properties\":{\"operation\":{\"type\":\"string\",\"enum\":[\"read\",\"write\",\"delete\"]},\"key\":{\"type\":\"string\"},\"value\":{\"type\":\"object\"}}}"
}
```

### Environment Event

External system interactions:

```json theme={null}
{
  "type": "environment",
  "content": "{\"source\":\"weather_api\",\"data\":{\"temperature\":22,\"conditions\":\"sunny\"}}",
  "schema": "{\"type\":\"object\",\"properties\":{\"source\":{\"type\":\"string\"},\"data\":{\"type\":\"object\"}}}"
}
```

## Handling Complex Data

### Images and Binary Data

For images and binary data, use base64 encoding within the JSON:

```python theme={null}
import base64

# Encode image
with open("image.png", "rb") as f:
    image_base64 = base64.b64encode(f.read()).decode('utf-8')

# Include in event
content = {
    "image": image_base64,
    "format": "png",
    "description": "User uploaded screenshot"
}

schema = {
    "type": "object",
    "properties": {
        "image": {
            "type": "string",
            "contentEncoding": "base64"
        },
        "format": {
            "type": "string",
            "enum": ["png", "jpg", "gif"]
        },
        "description": {
            "type": "string"
        }
    }
}
```

### Nested Structures

Support complex nested data structures:

```python theme={null}
content = {
    "order": {
        "id": "order-123",
        "customer": {
            "id": "cust-456",
            "name": "Alice Smith",
            "tier": "premium"
        },
        "items": [
            {
                "product_id": "prod-789",
                "quantity": 2,
                "price": 29.99
            }
        ],
        "metadata": {
            "source": "web",
            "campaign": "summer-sale"
        }
    }
}

# Schema can validate complex nested structures
schema = {
    "type": "object",
    "properties": {
        "order": {
            "type": "object",
            "properties": {
                "id": {"type": "string"},
                "customer": {
                    "type": "object",
                    "properties": {
                        "id": {"type": "string"},
                        "name": {"type": "string"},
                        "tier": {"type": "string"}
                    }
                },
                "items": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "product_id": {"type": "string"},
                            "quantity": {"type": "integer"},
                            "price": {"type": "number"}
                        }
                    }
                }
            }
        }
    }
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use Consistent Event IDs">
    Generate UUIDs for event IDs to ensure uniqueness:

    ```python theme={null}
    import uuid
    event_id = str(uuid.uuid4())
    ```
  </Accordion>

  <Accordion title="Include Relevant Context">
    Add contextual information that might be useful for analysis:

    ```python theme={null}
    content = {
        "action": "delete_file",
        "file": "/data/report.pdf",
        "reason": "User requested deletion",
        "user_id": "user-123",
        "ip_address": "192.168.1.1"
    }
    ```
  </Accordion>

  <Accordion title="Use Detailed Schemas">
    Include constraints, formats, and descriptions:

    ```python theme={null}
    schema = {
        "type": "object",
        "properties": {
            "email": {
                "type": "string",
                "format": "email",
                "description": "User's email address"
            },
            "age": {
                "type": "integer",
                "minimum": 0,
                "maximum": 150
            },
            "score": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "multipleOf": 0.1
            }
        },
        "required": ["email"],
        "additionalProperties": false
    }
    ```
  </Accordion>

  <Accordion title="Handle Errors Gracefully">
    Log errors as events for debugging:

    ```python theme={null}
    try:
        # Some operation
        result = risky_operation()
    except Exception as e:
        log_event(
            trace_id=trace_id,
            event_type="error",
            content=json.dumps({
                "error": str(e),
                "error_type": e.__class__.__name__,
                "context": {
                    "operation": "risky_operation",
                    "input": input_data
                }
            }),
            schema=error_schema
        )
    ```
  </Accordion>
</AccordionGroup>

## Validation

Fabraix validates all events against their schemas. Common validation errors:

<Warning>
  **Schema Mismatch**: Content doesn't match schema structure

  ```json theme={null}
  {
    "error": "Content validation failed",
    "details": "Required property 'user_id' missing"
  }
  ```
</Warning>

<Warning>
  **Invalid JSON**: Content or schema is not valid JSON

  ```json theme={null}
  {
    "error": "Invalid JSON in content field",
    "details": "Unexpected token at position 45"
  }
  ```
</Warning>

<Warning>
  **Type Mismatch**: Wrong data type for a field

  ```json theme={null}
  {
    "error": "Type validation failed",
    "details": "Expected string for 'age', got number"
  }
  ```
</Warning>

## Next Steps

Now that you understand the Event data model:

<CardGroup cols={2}>
  <Card title="Agent Lifecycle" icon="diagram-project" href="/essentials/agent-lifecycle">
    See how events flow through an agent's lifecycle
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/arx/endpoint/event">
    Explore the Event endpoint documentation
  </Card>
</CardGroup>
