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

# Sources & images

> Point a source at your data — JSONL, CSV, or images — and Splendor makes each file searchable automatically. Records and the images they reference become one searchable thing.

A **source** is where your data lives: a place you upload files to, or a bucket Splendor reads from. You don't tell a source what kind of data it holds. Drop in JSONL, CSV, or images and Splendor works out what each file is and makes it searchable — text files become searchable records, images become searchable by their visual content. One source can hold a mix of both.

<Tip>
  Because every file is handled on its own, a single source can hold your records *and* the images those records reference — no second source, no separate pipeline.
</Tip>

## What each file becomes

| You add                           | It becomes              | You find it by                                           |
| --------------------------------- | ----------------------- | -------------------------------------------------------- |
| A records file (`.jsonl`, `.csv`) | **Records**             | Keyword, SQL, and meaning across its fields              |
| An image a record points to       | Part of **that record** | The record's fields *and* what the image looks like      |
| An image nothing references       | A **standalone image**  | Visual similarity — an image library you search directly |

## Records that carry an image

A common, powerful pattern: a record that points at an image, found by **both** its fields and what the image actually looks like — with no duplicate entry for the image.

Say each product in your catalog has a photo. Tell the source which field holds the image:

```json theme={null}
{
  "source_key": "catalog",
  "name": "Product catalog",
  "dataset_id": "products",
  "source_type": "hosted",
  "semantic": {
    "image_embeddings": { "fields": ["photo_key"] }
  }
}
```

Then add records like:

```json theme={null}
{ "sku": "A-12", "name": "Walnut chair", "color": "brown", "photo_key": "images/a-12.png" }
```

Splendor reads that image from your source, understands it, and attaches that understanding to the record. A semantic search for "a brown wooden chair" (with `content_filter: "images"`) returns the **product record** — which you can still filter by `color = "brown"` like any other field. One record, found by what it says *and* what it looks like.

### Where the image lives

The image field can point three ways — always to data you own (a value can never reach storage that isn't yours):

| You write                   | Splendor looks in             | Use when                                          |
| --------------------------- | ----------------------------- | ------------------------------------------------- |
| `images/a-12.png`           | the same source as the record | the image sits next to your records (most common) |
| `splendor://<source>/<key>` | another source you own        | the image lives in a different source             |
| `s3://<bucket>/<key>`       | your own bucket               | your records already use absolute S3 paths        |

These are references to an object in a source you own — **not** public web URLs. Splendor never fetches an arbitrary `http(s)://` address. If your records carry image URLs (a scraped or third-party dataset), download the images into a source first — a [hosted upload](/guides/ingest-a-dataset) or your own S3 bucket — and reference the stored key.

Splendor reads each referenced image once, however many records reference it, and re-reads it automatically if you replace it — so visual search always reflects the current image. Supported image types: `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, added the same way as any other file.

## A searchable image library

If your records don't reference any images, the images in a source become **standalone** — each its own searchable document — so the source doubles as an image library you query by visual similarity.

If you want both at once — records that reference images *and* those images searchable on their own — turn it on explicitly:

```json theme={null}
{ "semantic": { "image_embeddings": { "fields": ["photo_key"], "index_standalone": true } } }
```

<Note>
  A field holds either text or an image reference, not both.
</Note>

## Next

<Columns cols={2}>
  <Card title="Ingest a dataset" icon="upload" href="/guides/ingest-a-dataset">
    Create a source and add your first records and images.
  </Card>

  <Card title="Semantic search" icon="wand-magic-sparkles" href="/guides/semantic-search">
    Search by meaning, including `content_filter: "images"` for visual matches.
  </Card>
</Columns>
