Skip to content

Request signed upload URL (recommended)

POST
/v1/workspaces/{workspace_id}/files/upload-url
curl --request POST \
--url https://api.app.layer.ai/api/v1/workspaces/:workspace_id/files/upload-url \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"content_type": "<string>",
"file_name": "<string>",
"file_size_bytes": 0,
"source_type": "pose"
}'

Get a signed URL to upload a file directly to storage, bypassing the server. This is the recommended upload method for large files.

Flow:

  1. Call this endpoint with content_type and file_size_bytes
  2. POST to the returned upload_url with header x-goog-resumable: start to get a session URI
  3. PUT your file content to the session URI (supports chunked/resumable uploads)
  4. Use the returned file_id as input to generation endpoints

Allowed types: application/x-zip-compressed, application/zip, audio/mpeg, audio/wav, image/jpeg, image/png, image/webp, video/mp4. Max size: 64 MB. Upload URL expires in 15 minutes.

workspace_id
required
Workspace Id
string format: uuid
Media typeapplication/json
RequestUploadUrlRequest
object
content_type
required
Content Type

MIME type of the file to upload.

string
file_name
Any of:
string
file_size_bytes
required
File Size Bytes

Expected file size in bytes. Used to enforce upload limits.

integer
> 0
source_type
Any of:
FileSourceType
string
Allowed values: pose reference mask composite google_drive transformed_reference skill_resource skill_bundle

Successful Response

Media typeapplication/json
RequestUploadUrlResponse
object
file_id
required
File Id

Unique identifier for the file. Use as input to generation endpoints after upload completes.

string format: uuid
upload_url
required
Upload Url

Signed upload URL. POST to this URL to initiate a resumable upload, then PUT file chunks to the session URI returned in the Location header. Expires in 15 minutes.

string
content_type
required
Content Type

MIME type to use when uploading.

string
source_type
Any of:
FileSourceType
string
Allowed values: pose reference mask composite google_drive transformed_reference skill_resource skill_bundle
Example
{
"source_type": "pose"
}

Unauthenticated — missing or invalid Bearer token.

Media typeapplication/problem+json
object
type
required
string
title
required
string
status
required
integer
detail
required
string
Example
{
"type": "https://api.layer.ai/errors/ERROR_CODE",
"title": "Error Title",
"status": 400,
"detail": "Human-readable description."
}

Forbidden — insufficient permissions.

Media typeapplication/problem+json
object
type
required
string
title
required
string
status
required
integer
detail
required
string
Example
{
"type": "https://api.layer.ai/errors/ERROR_CODE",
"title": "Error Title",
"status": 400,
"detail": "Human-readable description."
}

Resource not found.

Media typeapplication/problem+json
object
type
required
string
title
required
string
status
required
integer
detail
required
string
Example
{
"type": "https://api.layer.ai/errors/ERROR_CODE",
"title": "Error Title",
"status": 400,
"detail": "Human-readable description."
}

Invalid input parameters.

Media typeapplication/problem+json
object
type
required
string
title
required
string
status
required
integer
detail
required
string
Example
{
"type": "https://api.layer.ai/errors/ERROR_CODE",
"title": "Error Title",
"status": 400,
"detail": "Human-readable description."
}

Rate limited — too many concurrent requests.

Media typeapplication/problem+json
object
type
required
string
title
required
string
status
required
integer
detail
required
string
Example
{
"type": "https://api.layer.ai/errors/ERROR_CODE",
"title": "Error Title",
"status": 400,
"detail": "Human-readable description."
}

Internal server error.

Media typeapplication/problem+json
object
type
required
string
title
required
string
status
required
integer
detail
required
string
Example
{
"type": "https://api.layer.ai/errors/ERROR_CODE",
"title": "Error Title",
"status": 400,
"detail": "Human-readable description."
}