> For the complete documentation index, see [llms.txt](https://docs.graphlit.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.graphlit.dev/api-guides/use-cases/content/content-ingest-event.md).

# Ingest Event

## Content: Ingest Event

### User Intent

"I want to ingest time-series events or episodic memories into Graphlit for temporal search and recall"

### Operation

* **SDK Method**: `graphlit.ingestEvent()`
* **GraphQL**: `ingestEvent` mutation
* **Entity Type**: Content (Event subtype)
* **Common Use Cases**: User activity logs, calendar events, app events, journal entries, timeline data, audit logs

### TypeScript (Canonical)

```typescript
import { Graphlit } from 'graphlit-client';
import { ContentState, ObservableTypes } from 'graphlit-client/dist/generated/graphql-types';

const graphlit = new Graphlit();

// Ingest an event with timestamp
const response = await graphlit.ingestEvent(
  'User completed onboarding tutorial',    // markdown (event description)
  'Onboarding Completed',                  // name
  'New user finished the onboarding flow', // description (optional)
  new Date('2025-01-15T10:30:00Z')        // eventDate (when it occurred)
);

const eventId = response.ingestEvent.id;
console.log(`Event ingested: ${eventId}`);

// Retrieve the event
const content = await graphlit.getContent(eventId);
console.log(`Event text: ${content.content.markdown}`);
console.log(`Event date: ${content.content.eventDate}`);
```

## Ingest event (snake\_case method)

response = await graphlit.ingestEvent( markdown="User completed onboarding tutorial", name="Onboarding Completed", description="New user finished the onboarding flow", event\_date=datetime(2025, 1, 15, 10, 30, 0) )

event\_id = response.ingest\_event.id if response.ingest\_event else None

````

**C#**:
```csharp
using Graphlit;
using System;

var client = new Graphlit();

// Ingest event (PascalCase method)
var response = await graphlit.IngestEvent(
    markdown: "User completed onboarding tutorial",
    name: "Onboarding Completed",
    description: "New user finished the onboarding flow",
    eventDate: new DateTime(2025, 1, 15, 10, 30, 0, DateTimeKind.Utc)
);

var eventId = response.IngestEvent?.Id;
````

### Parameters

#### Required

* **`markdown`** (string): Event description/content
  * Should be descriptive and searchable
  * Can include markdown formatting
  * This becomes the event's main content
* **`name`** (string): Display name for the event (optional but recommended)

#### Optional

* **`description`** (string): Additional description of the event
  * Provides context beyond the markdown content
* **`eventDate`** (Date/DateTime): When the event occurred
  * **Critical**: This is the temporal anchor for the event
  * Used for chronological ordering and time-based queries
  * Must be ISO 8601 format or Date object
  * If omitted, uses current time
* **`id`** (string): Custom ID for the event
* **`identifier`** (string): Custom identifier for deduplication
* **`collections`** (EntityReferenceInput\[]): Collections to organize events
* **`correlationId`** (string): For tracking in production systems

### Response

```typescript
{
  ingestEvent: {
    id: string;                // Event ID
    name: string;              // Name you provided
    state: ContentState;       // FINISHED
    type: ContentEVENT;  // Always EVENT
    markdown: string;          // The event content
    description?: string;      // Description if provided
    eventDate: Date;           // Event timestamp
  }
}
```

### Developer Hints

#### Event vs Text vs Memory: Key Differences

| Aspect            | ingestEvent               | ingestText        | ingestMemory      |
| ----------------- | ------------------------- | ----------------- | ----------------- |
| **Purpose**       | Time-series events        | General content   | Semantic memories |
| **Timestamp**     | eventDate (specific time) | creationDate only | creationDate only |
| **Use Case**      | Calendar events, logs     | Documents, notes  | AI agent memory   |
| **Query Pattern** | Time-based filtering      | Full-text search  | Semantic search   |
| **Content Type**  | `EVENT`                   | `TEXT`            | `MEMORY`          |

#### When to Use ingestEvent

Use `ingestEvent` when:

* Events have a specific timestamp (when it happened matters)
* Building a timeline or activity log
* Tracking calendar events or milestones
* Creating audit trails
* Need temporal queries (e.g., "what happened last week?")
* Event occurred at a specific point in time

Use `ingestText` when:

* Content is timeless (e.g., documentation)
* Timestamp is not meaningful
* Just storing reference information

Use `ingestMemory` when:

* Storing semantic memories for AI agents
* Building conversational context
* Don't need specific event timestamps

#### 🕐 Understanding Timestamps

```typescript
// Current time
const now = new Date();
await graphlit.ingestMemory('Event just happened', 'Current Event', now, undefined, undefined, true);

// Past event
const pastDate = new Date('2025-01-01T12:00:00Z');
await graphlit.ingestMemory('New Year celebration', 'New Year', pastDate, undefined, undefined, true);

// Future event (scheduled)
const futureDate = new Date('2025-12-31T23:59:59Z');
await graphlit.ingestMemory('Year-end review scheduled', 'Future Event', futureDate, undefined, undefined, true);
```

**Important**: Timestamps enable time-range queries when searching memories.

### Variations

#### 1. Ingesting User Activity Log

Track user actions for personalization:

```typescript
// Create a collection for user activities
const collectionResponse = await graphlit.createCollection({
  name: 'User Activity Log'
});

const collectionId = collectionResponse.createCollection.id;

// Log multiple activities
const activities = [
  { text: 'User logged in', name: 'Login', timestamp: new Date('2025-01-15T09:00:00Z') },
  { text: 'User viewed product page: Widget A', name: 'Page View', timestamp: new Date('2025-01-15T09:05:00Z') },
  { text: 'User added Widget A to cart', name: 'Add to Cart', timestamp: new Date('2025-01-15T09:10:00Z') },
  { text: 'User completed purchase: $99.99', name: 'Purchase', timestamp: new Date('2025-01-15T09:15:00Z') }
];

for (const activity of activities) {
  await graphlit.ingestMemory(
    activity.text,
    activity.name,
    activity.timestamp,
    undefined,
    [{ id: collectionId }],
    true
  );
}

// Now you can query activities by time range
const filter = {
  collections: [collectionId],
  dateRange: {
    from: new Date('2025-01-15T09:00:00Z'),
    to: new Date('2025-01-15T09:30:00Z')
  }
};

const results = await graphlit.queryContents(filter);
console.log(`Found ${results.contents.results.length} activities in time range`);
```

#### 2. Ingesting with Entity Extraction

Extract structured data from memory text:

```typescript
// Create extraction workflow
const workflowInput: WorkflowInput = {
  name: 'Extract Memory Entities',
  extraction: {
    jobs: [
      {
        connector: {
          type: EntityExtractionServiceTypes.ModelText,
          modelText: {
            extractedTypes: [
              ObservableTypes.Person,
              ObservableTypes.Organization,
              ObservableTypes.Place,
              ObservableTypes.Event
            ]
          }
        }
      }
    ]
  }
};

const workflowResponse = await graphlit.createWorkflow(workflowInput);

// Ingest memory with extraction
const response = await graphlit.ingestMemory(
  'Had lunch with Sarah Johnson at Cafe Roma to discuss the partnership with TechCorp',
  'Business Lunch',
  new Date('2025-01-15T12:00:00Z'),
  { id: workflowResponse.createWorkflow.id },
  undefined,
  true  // Must be synchronous for workflow
);

// Retrieve with extracted entities
const content = await graphlit.getContent(response.ingestMemory.id);
// Will extract: Person (Sarah Johnson), Place (Cafe Roma), Organization (TechCorp)
console.log(`Extracted ${content.content.observations?.length || 0} entities from memory`);
```

#### 3. Building Conversation History

Store conversation turns as memories:

```typescript
const conversationId = 'user-123';
const collectionResponse = await graphlit.createCollection({
  name: `Conversation History - ${conversationId}`
});

const collectionId = collectionResponse.createCollection.id;

// User message
await graphlit.ingestMemory(
  'User asked: What are the best practices for API rate limiting?',
  `${conversationId} - User Message`,
  new Date(),
  undefined,
  [{ id: collectionId }],
  true
);

// Assistant response
await graphlit.ingestMemory(
  'Assistant responded: Here are the key strategies for API rate limiting: 1. Token bucket algorithm...',
  `${conversationId} - Assistant Message`,
  new Date(),
  undefined,
  [{ id: collectionId }],
  true
);

// Later, retrieve full conversation history
const filter = {
  collections: [collectionId],
  orderBy: 'CREATION_DATE',
  orderDirection: 'ASC'
};

const history = await graphlit.queryContents(filter);
// Chronologically ordered conversation
```

#### 4. Importing Historical Data

Bulk import past events:

```typescript
// Import calendar events from external system
const calendarEvents = [
  { description: 'Team standup meeting', date: '2025-01-10T10:00:00Z' },
  { description: 'Client presentation', date: '2025-01-12T14:00:00Z' },
  { description: 'Code review session', date: '2025-01-14T15:30:00Z' }
];

for (const event of calendarEvents) {
  await graphlit.ingestMemory(
    event.description,
    'Calendar Event',
    new Date(event.date),
    undefined,
    undefined,
    false  // Asynchronous for bulk import
  );
}

console.log(`Imported ${calendarEvents.length} historical events`);
```

### Common Issues

**Issue**: Memories not appearing in chronological order\
**Solution**: Ensure timestamps are correctly set. Use `orderBy: 'CREATION_DATE'` when querying.

**Issue**: `timestamp` parameter not accepted\
**Solution**: Ensure you're using a Date object (JavaScript) or datetime (Python), not a string. Or use ISO 8601 string format.

**Issue**: Cannot filter memories by date range\
**Solution**: When querying, use `dateRange` filter with `from` and `to` timestamps.

**Issue**: Workflow not extracting entities from memories\
**Solution**: Ensure workflow `extraction.jobs[].connector.type` is set to `EntityExtractionServiceTypes.ModelText` for text-based memory extraction.

### Production Example

**Server-side memory ingestion**:

```typescript
const response = await graphlit.ingestMemory(
  text,
  name,
  timestamp,
  workflow ? { id: workflow } : undefined,
  collections?.map((id) => ({ id })),
  isSynchronous
);
```

**Activity logging pattern**:

```typescript
// Log user activity with current timestamp
await graphlit.ingestMemory(
  `User ${userId} completed action: ${actionName}`,
  `Activity: ${actionName}`,
  new Date(),  // Current time
  undefined,
  [{ id: activityCollectionId }],
  true
);
```
