---
title: "Initiate a signed-URL raw-data upload"
method: POST
path: "/raw_data/initiate-upload"
tags: ["Raw Data"]
---

# Initiate a signed-URL raw-data upload

`POST /raw_data/initiate-upload`

Generate a signed upload URL. No DB record is created yet.

Returns the pre-generated raw-data ID and a single-element list of
signed-URL upload targets. The client PUTs the file bytes to the signed
URL and then calls the confirm endpoint to create the record. Each target
also carries an optional S3 ``multipart`` block, which clients use instead
of the signed URL for files too large for a single PUT.

## Request body

- InitiateRawDataUploadRequest — Body for POST /raw_data/initiate-upload. Carries the record metadata (project_id, name, source, metadata from RawDataBase) plus the original filename and optional content type needed to build the storage path and signed URL. No DB row is created.
  - `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 — Original filename to upload.
  - `content_type` string, nullable — MIME type, if known.

## Response `200`

Successful Response

- InitiateRawDataUploadResponse — Response from POST /raw_data/initiate-upload.
  - `raw_data_id` string, required — Pre-generated raw-data record ID.
  - `uploads` RawDataUploadInfo[], required — Signed-URL targets (always a single-element list).
    - `filename` string, required — Filename this signed URL targets.
    - `signed_url` string, required — Pre-signed URL to PUT the file to.
    - `token` string, required — Upload token from storage.
    - `path` string, required — Storage path within the raw-data bucket.
    - `multipart` MultipartUploadInfo — S3-multipart credentials and target for a large direct-to-storage upload. Mirrors the SDK-side model. The session token is the caller's own JWT, so Supabase Storage RLS applies to the S3 operations -- the service key must never appear in this block.
      - `endpoint` string, required — S3-compatible endpoint URL.
      - `region` string, required — S3 region name.
      - `bucket` string, required — Target storage bucket.
      - `object_path` string, required — Object key within the bucket.
      - `access_key_id` string, required — S3 access key id.
      - `secret_access_key` string, required — S3 secret access key.
      - `session_token` string, required — S3 session token (caller's JWT).
      - `expires_at` string, nullable — ISO timestamp after which the credentials stop working.

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