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

# Add a content source

> Create an index and get your records into Speedtrain so a task can run over them.

A task needs data to run over. In Speedtrain that data lives in an **index** — a collection of documents ingested from an external system.

## Create an index

<Steps>
  <Step title="Open Content sources">
    Go to **Content sources**. The **Indices** tab lists the indexes in the current environment; **Stage outputs** lists content generated by tasks.
  </Step>

  <Step title="Add an index">
    Click **Add index** and give it a name and an alias. The alias is the stable handle you use when pushing documents and when referencing the index elsewhere.
  </Step>

  <Step title="Push your documents">
    Send your records to the index through the ingestion API using a management client key. [Management clients](/speedtrain/settings/management-clients)
  </Step>
</Steps>

## Document shape

A document is a JSON object. Speedtrain reads whatever fields you send, so the shape is yours to decide — use the field names your source system already uses rather than inventing new ones.

```json theme={null}
{
  "id": "SKU-40128",
  "title": "Merino base layer",
  "category": "Base layers",
  "material": "100% merino wool",
  "weight_gsm": 180,
  "colour": "Charcoal"
}
```

<Tip>
  Send the raw attributes, not a pre-written summary. The model does better work from structured fields than from prose someone else already condensed.
</Tip>

### Images

If you want a vision model to see the product photos, add a top-level `$images` array:

```json theme={null}
{
  "id": "SKU-40128",
  "title": "Merino base layer",
  "$images": [
    { "url": "https://cdn.example.com/40128-front.jpg", "text": "Front view, charcoal" },
    { "url": "https://cdn.example.com/40128-detail.jpg" }
  ]
}
```

| Field  | Rules                                                                                                                                             |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`  | Required. Absolute `http(s)` and **publicly fetchable** — the model provider fetches it directly, so private or authenticated CDNs will not work. |
| `text` | Optional caption. It reaches the model as information about the image, never as an instruction.                                                   |

<Warning>
  `$images` must be at the top level and spelled exactly that way. A nested or differently-cased key is treated as ordinary data and ignored. A malformed `$images` array rejects the whole document at ingest, naming the offending element.
</Warning>

An empty `$images: []` is valid — "this document has no pictures" is a legitimate fact, and what happens next is decided by the task configuration. [Capabilities](/speedtrain/key-concepts/capabilities)

## Using another task's output instead

An index is not the only possible input. A task can also run over the accepted output of another task, which is how you chain jobs. You choose between the two when you start a session, not when you build the configuration. [Content sources](/speedtrain/key-concepts/content-sources)
