Skip to content
Guides · 미디어 업로드

미디어 업로드

사전 서명 R2 직접 업로드로 로컬 이미지, 비디오, 오디오를 AllToken에 전송합니다.


개요

비디오 생성과 이미지 편집 모두 미디어 자료를 사용합니다 — 참조 이미지, 참조 비디오와 오디오, 소스 이미지, 마스크. 이를 전송하는 방법에는 정확히 한 가지 규칙이 있습니다:

  • 자료가 이미 공개 인터넷에 있는 경우(당신의 CDN / 객체 스토리지) — 업로드 부담 없이 http(s) URL을 직접 전달합니다. 비디오 참조 소재에만 해당합니다.
  • 자료가 로컬에 있는 경우 — 사전 서명 R2 직접 업로드로 먼저 업로드한 다음, 반환된 upload_id를 참조합니다. 이것이 로컬 파일의 유일한 경로이며, 이미지 편집(소스와 마스크)의 유일한 경로입니다.

경고

data: base64 인라인 경로는 비디오 참조 소재에서 2026-08-06에 제거되었습니다. 이는 이미지 쪽(레거시 multipart 업로드가 앞서 제거됨)과 일치합니다. 로컬 미디어는 이제 항상 사전 서명 업로드를 거칩니다.

엔드포인트는 POST https://api.alltoken.ai/v1/uploads/presign입니다(복수형 uploads). 계정 서비스의 /upload/presign과 혼동하지 마세요. 후자는 사이트 내 아바타용이며 이미지 MIME 타입만 받습니다.

경로 선택

상황경로이유
비디오 참조 소재가 이미 당신의 CDN / OSS에 있음url 전달업로드가 전혀 없음 — 바이트가 우리 게이트웨이나 스토리지를 거치지 않음
비디오 참조 소재가 로컬에 있음(이미지 / 비디오 / 오디오)사전 서명 업로드로컬 파일의 유일한 경로
이미지 편집(/images/edits, /images/variations)의 소스와 마스크사전 서명 업로드파일 크기와 무관하게 유일한 진입점

3단계 업로드

파일은 우리 게이트웨이를 거치지 않습니다. 일회성 직접 업로드 URL을 발급받아 원시 바이트를 객체 스토리지로 직접 PUT한 다음, 작업을 생성할 때 반환된 upload_id를 참조합니다. 게이트웨이는 수십 바이트짜리 ID만 운반합니다. 동일한 메커니즘이 비디오 참조 소재와 이미지 편집에 모두 쓰이며, 차이는 purpose와 그것을 참조하는 필드뿐입니다.

1단계 — 직접 업로드 URL 요청:

사전 서명 요청
$POST https://api.alltoken.ai/v1/uploads/presign

본문: purpose(허용되는 MIME와 크기를 결정 — 아래 참조), content_type(파일 MIME, 소문자), content_length(정확한 바이트 수), content_md5, checksum_sha256.

경고

두 다이제스트는 인코딩 방식이 다릅니다: content_md5base64, checksum_sha256hex입니다. 둘을 바꿔 넣으면 presign 단계에서 400으로 거부됩니다.

응답은 upload_id(upl_로 시작), upload_url(사전 서명된 PUT 대상), required_headers(2단계에서 그대로 재전송), expires_in(URL 유효 기간, 300초), claim_expires_at(upload_id 유효 기간, 2시간), max_content_length를 반환합니다.

2단계 — 원시 바이트를 upload_url로 PUT하며, required_headers의 모든 헤더를 그대로 재전송합니다. 본문은 원시 파일 바이트입니다 — base64도 multipart도 아닙니다:

객체 스토리지로 PUT
1PUT <upload_url>
2Content-Type: video/mp4
3Content-MD5: N0xUuLBP5C0uKJ2i0fA1kA==
4
5<원시 바이트>

경고

필수 헤더를 빠뜨리거나 바꿔 쓰면 객체 스토리지가 403을 반환합니다 — 사전 서명 URL이 그 헤더들도 서명하기 때문입니다. Content-Encoding을 임의로 추가하지 말고, gzip을 쓰지 말고, multipart를 쓰지 마세요.

3단계 — upload_id를 참조하여 작업을 생성합니다. 비디오는 이를 content[].upload_id에 넣고, 이미지 편집은 image_upload_id / mask_upload_id 최상위 필드를 사용합니다. 게이트웨이는 바이트 수와 ETag를 검증하고, 객체를 해당 작업의 영구 영역으로 이동시키고, 업스트림에서 접근 가능한 주소를 제출합니다 — 이 모든 과정이 당신에게 투명하며, 당신은 202 + task_id만 받습니다.

기억해야 할 세 가지 규칙:

  • 한 항목 안에서 upload_id와 URL 필드는 상호 배타적입니다 — 둘 다 채우면 400 upload_url_conflict를 반환합니다.
  • presign과 작업 생성은 같은 API 키를 사용해야 합니다 — 소유권은 (사용자 + API 키 + purpose)로 확인되며, 키를 바꾸면 404 upload_not_found를 반환합니다.
  • purpose는 실제 용도와 일치해야 하며, 그렇지 않으면 마찬가지로 404 upload_not_found가 반환됩니다.

전체 요청 / 응답 필드 표는 이미지 API비디오 API 참조에 있습니다.

purpose 참조

purpose는 허용되는 MIME 타입과 파일당 크기 상한을 고정합니다.

purpose용도허용 MIME파일당 상한
video_input_image비디오 참조 이미지 / 첫·마지막 프레임image/png, image/jpeg, image/webp, image/gif20 MiB
video_input_video비디오 참조 비디오video/mp4, video/quicktime, video/webm100 MiB
video_input_audio비디오 참조 오디오audio/wav, audio/mpeg, audio/mp4, audio/aac, audio/ogg20 MiB
image_edit_source이미지 편집 소스image/png, image/jpeg, image/webp25 MiB
image_edit_mask이미지 편집 마스크image/png, image/webp (jpeg 불가)25 MiB
image_variation_source이미지 변형 소스image/png, image/jpeg, image/webp25 MiB

마스크가 image/jpeg를 거부하는 이유는 알파 채널로 "어디를 바꿀지"를 표현해야 하는데, jpeg에는 투명도가 없기 때문입니다.

시간 창과 쿼터

시간 창길이만료 후
upload_url(PUT 대상)5분PUT가 403 반환 — 다시 presign
upload_id(자료 클레임)2시간작업 생성이 409 upload_expired 반환

따라서: URL을 받는 즉시 업로드하되, 그 이후에는 두 시간 동안 여유롭게 생성 요청을 조립하여 제출할 수 있습니다.

upload_id정확히 하나의 작업에만 바인딩됩니다. 재사용하면 409 upload_already_used를 반환합니다. 이는 의도된 설계입니다 — 하나의 자료, 하나의 작업, 하나의 청구. 작업 생성이 실패하면 임시 객체는 자동으로 회수됩니다.

쿼터임계값초과 시
동시에 미사용 상태인 upload_id100429 quota_exceeded
UTC 하루당 업로드 총 바이트2 GiB429 quota_exceeded

정상적인 "업로드 후 사용" 페이스라면 이 한도에 닿을 일이 없습니다. 대규모 이미지 편집 배치에서는 일일 상한에 유의하세요: 25 MiB × 약 80개 파일이면 2 GiB에 도달합니다.

업로드 오류 코드

Presign 단계:

HTTPcode의미
400invalid_purposepurpose를 잘못 입력했거나 지원되지 않음
400invalid_content_typeMIME가 해당 purpose 화이트리스트에 없음(마스크를 jpeg로 보내면 여기에 해당)
400invalid_content_md5MD5가 유효한 base64가 아님(hex를 보내지 마세요)
400invalid_checksumSHA-256이 64자 소문자 hex가 아님(base64를 보내지 마세요)
413payload_too_largecontent_length가 해당 purpose 상한을 초과
429quota_exceededpending 100개 초과, 또는 당일 2 GiB 초과
503storage_unavailable스토리지 일시 중단 — 재시도

바인딩 단계(작업 생성 시):

HTTPcode의미
404upload_not_found알 수 없는 upload_id, 잘못된 API 키, 또는 purpose 불일치
409upload_already_used이미 작업에 바인딩됨 — 다시 presign
409upload_expired2시간 초과 — 다시 presign
400upload_object_missingpresign만 하고 PUT하지 않은 채 작업 생성
400upload_size_mismatch실제 바이트 수가 content_length와 다름
409upload_modified업로드 후 객체가 변경됨(ETag 불일치)
400upload_url_conflict한 항목에 upload_id와 URL 필드를 모두 설정