Ingest Text

Content: Ingest Text

User Intent

"I want to ingest plain text directly into Graphlit without a file or URL"

Operation

  • SDK Method: graphlit.ingestText()

  • GraphQL: ingestText mutation

  • Entity Type: Content

  • Common Use Cases: User-generated notes, chat messages, API responses, scraped text, clipboard content

TypeScript (Canonical)

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

const graphlit = new Graphlit();

// Basic text ingestion (synchronous)
const response = await graphlit.ingestText(
  'This is my note about the project meeting. We discussed Q1 goals and timeline.',  // text
  'Meeting Notes - January 2025',  // name
  undefined,  // textType (optional)
  undefined,  // uri (optional - for reference)
  undefined,  // id (optional)
  undefined,  // identifier (optional)
  true,       // isSynchronous
  undefined,  // workflow (optional)
  undefined   // collections (optional)
);

const contentId = response.ingestText.id;
console.log(`Text ingested: ${contentId}`);

// Retrieve the content
const content = await graphlit.getContent(contentId);
console.log(`Content markdown: ${content.content.markdown}`);

Ingest text (snake_case method)

Note: Python SDK uses named parameters, order doesn't matter

response = await graphlit.ingestText( text="This is my note about the project meeting.", name="Meeting Notes - January 2025", is_synchronous=True )

content_id = response.ingest_text.id if response.ingest_text else None


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

var client = new Graphlit();

// Ingest text (PascalCase method)
var response = await graphlit.IngestText(
    text: "This is my note about the project meeting.",
    name: "Meeting Notes - January 2025",
    isSynchronous: true
);

var contentId = response.IngestText?.Id;

Parameters

Required

  • text (string): The text content to ingest

    • Can be plain text or markdown

    • No size limit specified, but keep reasonable for performance

Optional

  • name (string): Display name for the content

  • textType (TextTypes): Type hint for the text

    • PLAIN - Plain text (default)

    • MARKDOWN - Markdown formatted text

  • uri (string): Optional reference URI for the text source

  • id (string): Custom ID for the content

  • identifier (string): Custom identifier for deduplication

  • isSynchronous (boolean): Wait for ingestion to complete

    • Default: false (asynchronous)

    • Recommended: true for immediate use

  • workflow (EntityReferenceInput): Workflow to apply during ingestion

  • collections (EntityReferenceInput[]): Collections to add content to

  • observations (ObservationReferenceInput[]): Observations to link

  • correlationId (string): For tracking in production systems

Response

{
  ingestText: {
    id: string;              // Content ID
    name: string;            // Name you provided
    state: ContentState;     // FINISHED (if synchronous)
    type: ContentTEXT; // Always TEXT
    markdown: string;        // The ingested text
    textType?: TextTypes;    // PLAIN or MARKDOWN
    uri?: string;            // Reference URI if provided
  }
}

Developer Hints

Key Differences from ingestUri

  1. No file parsing needed - Text is used directly, no extraction step

  2. Immediate availability - Even with isSynchronous: false, text is usually available immediately

  3. No file metadata - No fileType, mimeType, or file-specific fields

  4. Markdown support - Can ingest pre-formatted markdown

When to Use ingestText vs ingestUri

Use ingestText when:

  • You already have the text in memory

  • Text comes from user input, API, or database

  • No file parsing needed

  • You want to store snippets, notes, or short content

Use ingestUri when:

  • Content is in a file (PDF, DOCX, etc.)

  • Need file parsing/extraction

  • Content is at a URL

Understanding isSynchronous

// Asynchronous (default) - returns immediately
const response = await graphlit.ingestText(text, name, undefined, undefined, undefined, undefined, false);
// Content ID available immediately, processing happens in background

// Synchronous - waits for processing
const response = await graphlit.ingestText(text, name, undefined, undefined, undefined, undefined, true);
// Returns when content.state === 'FINISHED'

For ingestText, the difference is minimal since text doesn't require heavy processing. However, if you're using a workflow (e.g., entity extraction), synchronous mode ensures the workflow completes before returning.

Variations

1. Ingesting with Collections

Organize text into collections during ingestion:

// Create a collection first
const collectionResponse = await graphlit.createCollection({
  name: 'Meeting Notes'
});

const collectionId = collectionResponse.createCollection.id;

// Ingest text into collection
const response = await graphlit.ingestText(
  'Discussion about Q1 product roadmap and feature priorities.',
  'Product Planning Meeting',
  undefined,  // textType
  undefined,  // uri
  undefined,  // workflow
  [{ id: collectionId }],  // collections
  true
);

2. Ingesting Markdown

Preserve markdown formatting:

const markdownText = `
# Project Update

## Completed Tasks
- Feature A implementation
- Bug fixes in module B

## Next Steps
- Code review
- Deployment planning
`;

const response = await graphlit.ingestText(
  markdownText,
  'Weekly Project Update',
  TextTypes.Markdown,  // Specify markdown type
  undefined,
  undefined,
  undefined,
  true
);

// The markdown structure is preserved
const content = await graphlit.getContent(response.ingestText.id);
console.log(content.content.markdown); // Includes formatting

3. Ingesting with Entity Extraction

Apply a workflow to extract entities from text:

// Create extraction workflow
const workflowInput: WorkflowInput = {
  name: 'Extract People and Orgs',
  extraction: {
    jobs: [
      {
        connector: {
          type: EntityExtractionServiceTypes.ModelText,
          modelText: {
            extractedTypes: [
              ObservableTypes.Person,
              ObservableTypes.Organization
            ]
          }
        }
      }
    ]
  }
};

const workflowResponse = await graphlit.createWorkflow(workflowInput);

// Ingest text with extraction
const response = await graphlit.ingestText(
  'John Smith from Acme Corp discussed the partnership with Jane Doe from TechCo.',
  'Partnership Discussion',
  undefined,
  undefined,
  { id: workflowResponse.createWorkflow.id },  // workflow
  undefined,
  true  // Must be synchronous to wait for extraction
);

// Retrieve with extracted entities
const content = await graphlit.getContent(response.ingestText.id);
console.log(`Extracted ${content.content.observations?.length || 0} entities`);
// Will include Person entities for "John Smith" and "Jane Doe"
// Will include Organization entities for "Acme Corp" and "TechCo"

4. Ingesting with Reference URI

Track the source of text:

// Text scraped from a web API
const scrapedText = 'Product description from external API...';

const response = await graphlit.ingestText(
  scrapedText,
  'Product Description - Widget A',
  TextTypes.Plain,
  'https://api.example.com/products/widget-a',  // Reference URI
  undefined,
  undefined,
  true
);

// The URI is stored for reference
const content = await graphlit.getContent(response.ingestText.id);
console.log(`Source: ${content.content.uri}`);

Common Issues

Issue: Text ingested but not appearing in search Solution: Ensure embeddings are generated. Check project configuration for embedding model. If using asynchronous mode, wait a few seconds for embedding generation.

Issue: Special characters or formatting lost Solution: Use textType: TextTypes.Markdown if your text includes markdown formatting. Plain text is default.

Issue: Workflow not executing Solution: Must use isSynchronous: true when applying workflows. Asynchronous mode may return before workflow completes.

Issue: Content state is AWAITING_EXTRACTION Solution: Wait for processing to complete if using asynchronous mode. Or switch to synchronous mode.

Production Example

From Public Samples:

// Server-side text ingestion with all options
const response = await graphlit.ingestText(
  text,
  name,
  textType as TextTypes | undefined,
  uri,
  workflow ? { id: workflow } : undefined,
  collections?.map((id) => ({ id })),
  isSynchronous
);

Re-ingesting updated text:

// Update content by re-ingesting with same name
const response = await graphlit.ingestText(
  editedText,
  originalName,
  TextTypes.Plain,
  undefined,
  undefined,
  undefined,
  true
);

Last updated

Was this helpful?