---
title: "Request a signed URL for upload"
method: POST
path: "/v2/media/upload/request"
tags: ["v2 - Media"]
---

# Request a signed URL for upload

`POST /v2/media/upload/request`

## Request

- Base URL: `https://api.jubjubapp.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.jubjubapp.com/v2/media/upload/request`
- Auth: HTTP bearer

Start the upload process by requesting a signed URL.

    The frontend should:
    1. Call this endpoint with filename and optional content_type
    2. Use the returned signed_url to PUT the file directly to GCS
    3. Call /v2/media/{media_id}/upload/complete when done

    The signed URL is valid for 10 minutes.

## Headers

- `Authorization` string
- `X-JubJub-Service-Key` string
- `X-JubJub-Agent-Key` string
- `X-JubJub-Platform-Key` string
- `Origin` string
- `Referer` string
- `X-JubJub-Trial-Token` string

## Request body

- MediaUploadRequestDTO: Request to initiate a media upload. The frontend sends this to get a signed URL for direct upload to GCS.
  - `workspace_id` string, required: Workspace that will own this media
  - `filename` string, required: Original filename (e.g., 'video.mp4'). Used to detect content_type if not provided.
  - `content_type` string, nullable: MIME type. Auto-detected from filename extension if not provided.
  - `media_type` 'video' | 'image' | 'subtitle' | 'document': Type of media being uploaded. `document` is a PDF. An image/* or application/pdf mime sent with the default `video` is stored as an image or a document.
  - `size_bytes` integer, nullable: Total file size in bytes. REQUIRED for a document (PDF, at most 25 MB) and an image (at most 30 MB): 400 without it, 413 over the cap. When provided, the backend also returns a resumable_url for chunked uploads.

## Response `201`

Successful Response

- MediaUploadResponseDTO: Response with signed URL for upload. The frontend uses signed_url to PUT the file directly to GCS.
  - `media_id` string, required: ID of the created Media record
  - `signed_url` string, required: Signed URL for single PUT upload. Use for small files or as fallback.
  - `resumable_url` string, nullable: Resumable session URL for chunked uploads. Use PUT with Content-Range headers. Available when size_bytes is provided in the request.
  - `expires_at` string, date-time, required: When the signed URL expires. Upload must complete before this.
  - `gcs_path` string, required: Path where the file will be stored in GCS.
  - `content_type` string, required: Content-Type header to use when uploading.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/jubjubapp/apis/jubjub-api.md) - [All operations](https://skmtc.dev/jubjubapp/apis/jubjub-api/llms.txt) - [OpenAPI document](https://skmtc.dev/jubjubapp/apis/jubjub-api/revisions/353157b296f2?raw)
