> ## 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.

# Ingest a dataset

> Create a hosted source and upload a file so its records become searchable.

This guide loads data into Splendor through a **hosted source** — storage Splendor manages for you — using a resumable multipart upload. By the end you will have a dataset you can search.

## Prerequisites

* An admin role in the tenant (creating sources and tokens requires admin).
* A file of records to upload (for example, newline-delimited JSON).

Two credentials appear below: your **admin bearer token** (with the `X-Splendor-Tenant-Id` header) for the `/v1/admin/...` calls, and the source's **ingest token** for the `/v1/ingest/sources/...` calls. The ingest token carries the source and tenant itself, so those calls need no tenant header.

## Steps

<Steps>
  <Step title="Create a hosted source">
    A source is where your data lands and which dataset it feeds. Create a hosted source once, then reuse it for every upload. Splendor detects each file's type automatically, so one source can hold records and images together (see [Sources & images](/concepts/sources-and-assets)).

    ```bash theme={null}
    curl https://api.withsplendor.com/v1/admin/hosted-sources \
      -H "Authorization: Bearer $SPLENDOR_TOKEN" \
      -H "X-Splendor-Tenant-Id: $SPLENDOR_TENANT_ID" \
      -H "Content-Type: application/json" \
      -d '{
        "source_key": "app-logs",
        "name": "Application logs",
        "dataset_id": "app-logs",
        "source_type": "hosted"
      }'
    ```
  </Step>

  <Step title="Mint an ingest token">
    Mint a token for the source (using its numeric `source_id` from the previous response). The plaintext token is returned once; use it as the bearer credential for every upload call below.

    ```bash theme={null}
    curl -X POST https://api.withsplendor.com/v1/admin/sources/$SOURCE_ID/ingest-token \
      -H "Authorization: Bearer $SPLENDOR_TOKEN" \
      -H "X-Splendor-Tenant-Id: $SPLENDOR_TENANT_ID"
    ```
  </Step>

  <Step title="Initiate an upload">
    Start an upload session for your file. The response tells you whether to upload in a single request or in parts, and returns an `upload_session_id`.

    ```bash theme={null}
    curl https://api.withsplendor.com/v1/ingest/sources/app-logs/uploads \
      -H "Authorization: Bearer $SPLENDOR_INGEST_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"object_size_bytes": 5242880, "content_type": "application/x-ndjson", "filename": "app-0001.jsonl"}'
    ```
  </Step>

  <Step title="Sign and upload the parts">
    Request presigned URLs for your part numbers, then `PUT` each chunk directly to the returned URL. Keep the `ETag` each upload returns.

    ```bash theme={null}
    curl https://api.withsplendor.com/v1/ingest/sources/app-logs/uploads/parts \
      -H "Authorization: Bearer $SPLENDOR_INGEST_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"upload_session_id": "ups_...", "part_numbers": [1]}'
    ```
  </Step>

  <Step title="Complete the upload">
    Finalize the upload with the part numbers and their ETags. This enqueues the object for ingestion.

    ```bash theme={null}
    curl https://api.withsplendor.com/v1/ingest/sources/app-logs/uploads/complete \
      -H "Authorization: Bearer $SPLENDOR_INGEST_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"upload_session_id": "ups_...", "parts": [{"part_number": 1, "etag": "\"...\""}]}'
    ```
  </Step>

  <Step title="Wait until it is searchable">
    Ingestion is asynchronous. Poll the upload's readiness until text and semantic search are ready.

    ```bash theme={null}
    curl https://api.withsplendor.com/v1/ingest/sources/app-logs/uploads/ups_.../readiness \
      -H "Authorization: Bearer $SPLENDOR_INGEST_TOKEN"
    ```
  </Step>
</Steps>

<Check>
  When readiness reports `text_search` (and, if configured, `semantic_search`) ready, [run a search](/quickstart) against the dataset.
</Check>

## Related

<Columns cols={2}>
  <Card title="Stream logs" icon="scroll" href="/guides/stream-logs">
    Send log records continuously instead of uploading files.
  </Card>

  <Card title="Connect a source" icon="plug" href="/guides/connect-a-source">
    Push data over HTTP — including from a webhook — or read from your own S3 bucket.
  </Card>
</Columns>
