---
title: "Confirm a signed-URL raw-data upload"
method: POST
path: "/raw_data/{raw_data_id}/confirm-upload"
tags: ["Raw Data"]
---

# Confirm a signed-URL raw-data upload

`POST /raw_data/{raw_data_id}/confirm-upload`

Verify the file landed in storage, then create the DB record.

The storage path is recomputed server-side from ``organization_id``,
``raw_data_id`` and ``filename``; a client-supplied path is never trusted.

## Path parameters

- `raw_data_id` string, required

## Request body

- ConfirmRawDataUploadRequest — Body for POST /raw_data/{raw_data_id}/confirm-upload. Repeats the record metadata (same as initiate, so no orphan record is created if the PUT fails) plus the uploaded file's filename, content type, and client-computed size. The server recomputes the storage path from organization_id + raw_data_id + filename; a client-supplied path is never trusted.
  - `project_id` string, required — Owning project ID (required).
  - `name` string, required — User-provided label for the raw file.
  - `source` string, nullable — Free-text provenance: where this raw file came from (a URL, DOI, S3 URI, vendor/cycler export description, etc.).
  - `metadata` object — Loose free-form metadata.
  - `filename` string, required — Filename that was uploaded.
  - `content_type` string, nullable — MIME type, if known.
  - `size_bytes` integer, nullable — File size in bytes, computed client-side.
  - `process` boolean — Start server-side ingestion (parse, validate, review queue) immediately. Defaults to False: clients that process the file themselves and upload the resulting measurement would otherwise get a second, server-derived attempt at the same file. Records left unprocessed are still picked up by the raw-data scan.

## Response `201`

Successful Response

- RawData — A raw-data record as returned by the API.
  - `project_id` string, required — Owning project ID (required).
  - `name` string, required — User-provided label for the raw file.
  - `source` string, nullable — Free-text provenance: where this raw file came from (a URL, DOI, S3 URI, vendor/cycler export description, etc.).
  - `metadata` object — Loose free-form metadata.
  - `id` string, required — Unique identifier.
  - `organization_id` string, required — Owning organization.
  - `filename` string, required — Original uploaded filename.
  - `content_type` string, nullable — MIME type, if known.
  - `size_bytes` integer, nullable — File size in bytes.
  - `storage_path` string, required — Path within the raw-data bucket.
  - `processing_status` 'pending' | 'queued' | 'processing' | 'needs_review' | 'awaiting_cell' | 'done' | 'failed' — Ingestion lifecycle: pending | queued | processing | needs_review | awaiting_cell | done | failed. See src.pydantic_models.raw_data_ingestion for what each means.
  - `processing_error` string, nullable — Terminal ingestion failure message, if any.
  - `processed_at` string, date-time, nullable — When ingestion last reached a terminal state.
  - `reader` string, nullable — Cycler format detected on parse (arbin, maccor, ...).
  - `created_by` string, nullable — User ID of the uploader.
  - `created_at` string, date-time, required — Creation timestamp.
  - `updated_at` string, date-time, required — Last update timestamp.

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/ionworks/apis/fastapi.md) · [All operations](https://skmtc.dev/ionworks/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/ionworks/fastapi/revisions/7337a3cbdaf2/schema)
