# Saving text (https://brainapi.lumen-labs.ai/docs/v2/ingestion/text)

> For the complete BrainAPI documentation index, see [llms.txt](https://brainapi.lumen-labs.ai/docs/llms.txt). A markdown version of any docs page is available by appending `.md` to its URL (e.g. https://brainapi.lumen-labs.ai/docs/v2/ingestion/text.md).

How to save text to the memory store

Ingesting text is the simplest way to save information into a memory store. Storing simple text is useful in most of the cases,
such as powering memory for chatbots and ai assistants, but also to power a RAG pipeline for a set of documents.

`POST /ingest/` returns **202 Accepted** with `{ "message": "Ingestion accepted", "task_id": "…" }`. Poll progress with [ingestion tasks](https://brainapi.lumen-labs.ai/docs/v2/ingestion/tasks). Optionally send a `Task-Identifier` header to pin the Celery task id.

<AgentNote>
- `POST /ingest/` with `Content-Type: application/json`, `BrainPAT`, brain scope
- Required shape: `{ "data": { "data_type": "text", "text_data": "…" }, "brain_id"? }`
- **202** + `task_id` → poll `GET /tasks/{id}`; **404** ≠ pending
- Optional: `Task-Identifier` header, `observate_for`, `meta_keys`, `identification_params`
- Set `skip_enrichment=true` for chunk + embedding only (useful for search corpora)
</AgentNote>

## Usage

The text ingestion API is available via the REST API, Python SDK, and TypeScript SDK.
The API payload consists of one main section: `data.text_data`, which contains the text to ingest; the optional fields
`meta_keys`, `identification_params` and `observate_for` array, are used to tailor the analysis and provide metadata.

<Tabs items={["Typescript", "Python", "cURL"]}>
  <Tab value="Typescript">
    The Typescript SDK provides the `ingestText` function to ingest plain text.
    <DynamicCodeBlock
      lang="ts"
      code={`
const result = await brain.ingestText({
    text: "This is a plain text to ingest into the memory store.",
    observate_for: [], // optional instructions to tailor the analysis
    brain_id: "example01",
});`}
    />
  </Tab>
  <Tab value="Python">
    The Python SDK provides the `ingest_text` method to ingest plain text.
    <DynamicCodeBlock
      lang="py"
      code={`result = await client.ingest_text(
    text="This is a plain text to ingest into the memory store.",
    observate_for=[], // optional instructions to tailor the analysis
    brain_id="example01",
)`}
    />
  </Tab>
  <Tab value="cURL">
    Call the POST endpoint with the payload to ingest plain text. Expect HTTP 202 and a `task_id`.
    <DynamicCodeBlock
      lang="bash"
      code={`curl -X POST "<DEPLOYMENT_URL>/ingest/" \\
      -H "Content-Type: application/json" \\
      -H "X-Brain-ID: mybrain123" \\
      -H "BrainPAT: YOUR_BRAIN_PAT" \\
      -d '{
        "data": {
          "data_type": "text",
          "text_data": "Alice met Bob at Acme Corp in 2024."
        },
        "meta_keys": {"email": "alice@example.com"},
        "identification_params": {"source": "crm"},
        "observate_for": ["people", "companies", "dates"],
        "preferred_extraction_entities": ["Person", "Company"]
      }'
# → {"message":"Ingestion accepted","task_id":"…"}`}
    />
  </Tab>
</Tabs>

<Callout type="info">
  After 202, poll `GET /tasks/` with the returned task id until the job finishes.
  A missing task returns **404** (not soft pending). See [Ingestion tasks](https://brainapi.lumen-labs.ai/docs/v2/ingestion/tasks).
</Callout>

## Parameters information

Below you can find more information about the parameters that can be used to ingest plain text.

### `text_data`, field inside `data`

This field will contain accept only plain text that will be saved into the memory store:

### `meta_keys` optional parameter

This is an object that carring the metadata that will be attached to the text and that will not be used in the analysis.

### `identification_params` optional parameter

This is an object that will contain the key value pairs that will be used to identify an entity that is associated with the saved text.

### `observate_for` optional parameter

This is a list of strings that will be used to tailor the analysis of the saved text, (eg. "Looking for new ways to improve the product" or "Planning a new trip to Paris").

### `preferred_extraction_entities` optional parameter

This is a list of strings that if provided will be used to used to constrain the types of entities that will be extracted from the saved text and used to create the entity graph.

## Search-only ingestion

Set `skip_enrichment=true` when the text should be searchable but does not need
observations or an automatically extracted knowledge graph:

```bash
curl -X POST "<DEPLOYMENT_URL>/ingest/" \
  -H "Content-Type: application/json" \
  -H "BrainPAT: YOUR_BRAIN_PAT" \
  -H "X-Brain-ID: products" \
  -d '{
    "data": {
      "data_type": "text",
      "text_data": "DOCID sku-42. Modern oak dining table"
    },
    "skip_enrichment": true
  }'
```

The worker still saves the text chunk, calculates its embedding, and marks the
task complete. It skips Observations, Scout, and Architect work. This reduces
ingestion cost for search benchmarks and explicitly managed catalogs. It does
not create product nodes or attribute edges; add those through [structured
ingestion](https://brainapi.lumen-labs.ai/docs/v2/ingestion/structured-data).
