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)

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

{
  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

// 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:

// 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:

// 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:

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:

// 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:

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

Activity logging pattern:

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

Last updated

Was this helpful?