REST API
HTTP를 통해 파일 업로드, 컬렉션 생성, 공유 관리. 모든 응답은 JSON이며, 익명 업로드에는 API 키가 필요 없습니다.
소개
storage.to API는 CLI, 데스크탑 앱, 웹 업로더 및 여러분이 만들고 싶은 모든 서드파티 클라이언트를 지원합니다.
업로드 과정은 세 단계입니다:
- 초기화 — 파일 업로드 의사를 알려주세요. Cloudflare R2를 가리키는 하나 이상의 사전 서명 URL을 반환합니다.
- R2에 업로드 —
PUT을 사용해 바이트를 사전 서명된 URL에 직접 전송하세요. 바이트는 당사 서버를 거치지 않습니다. - 확인 — 업로드가 완료되었음을 알려주세요.
File기록을 생성하고 공유 가능한 URL을 제공합니다.
기본 URL
https://storage.to/api
아래 모든 엔드포인트는 이 기본 URL을 기준으로 합니다. 예: POST /upload/init는 POST https://storage.to/api/upload/init을 의미합니다.
인증
대부분의 엔드포인트는 인증이 필요하지 않습니다. 익명 업로드는 핵심 기능입니다.
인증은 선택 사항이며 다음을 활성화합니다:
- 계정에 연결된 업로드 (/dashboard에서 확인 가능)
- 프리미엄 기능 (영구 파일, 더 큰 저장 공간)
- 방문자 토큰 일치 없이 소유권 기반 변경(삭제, 비밀번호 설정, 만료 변경)
Laravel Sanctum 베어러 토큰을 사용합니다. 데스크탑 OAuth 연동 또는 웹 로그인으로 토큰을 발급받아 다음과 같이 전송하세요:
Authorization: Bearer <token>
방문자 토큰
익명 클라이언트는 계정 없이도 자신의 업로드 소유권을 증명할 방법이 필요합니다. 방문자 토큰를 사용하며, 클라이언트가 한 번 생성해 재사용하는 임의 문자열입니다. 모든 요청에 함께 전송하세요:
X-Visitor-Token: <random-string>
웹에서는 토큰이 자동으로 visitor_token 쿠키에 저장됩니다. CLI는 ~/.config/storageto/token에 저장합니다 (CLI 문서 참조).
변경 엔드포인트(삭제, 비밀번호 설정, 만료 변경)의 경우, 소유권은 또는 방문자 토큰이 일치하거나 또는 요청이 파일을 생성한 동일 IP에서 온 경우 확인됩니다.
오류
오류는 일관된 형식을 따릅니다:
{
"success": false,
"error": "Human-readable message"
}
일반적인 HTTP 상태 코드:
| 코드 | 의미 |
|---|---|
200 | 성공. |
201 | 생성됨. |
400 | 잘못된 요청 (예: 컬렉션 크기 제한 초과). |
401 | 비밀번호 필요 또는 틀림. |
403 | 권한 없음 (자원 소유자가 아님). |
404 | 자원을 찾을 수 없거나 만료됨. |
422 | 검증 실패 또는 요금제/할당량 제한. |
429 | 요청 제한 또는 업로드 할당량 초과. |
500 | 서버 오류. 상태를 확인하세요. |
요청 제한
모든 요청 제한은 IP별로 적용됩니다. 429 응답에는 표준 Retry-After, X-RateLimit-Limit, 및 X-RateLimit-Remaining 헤더가 포함됩니다.
| 범위 | 제한 |
|---|---|
| 업로드 시작 / 확인 / 중단 | 60 / 분 |
| 멀티파트 완료 | 500 / 분 |
| 멀티파트 파트 URL | 120 / 분 |
| 일괄 시작 / 확인 | 500 / 분 |
| 상태 조회 (파일 및 컬렉션) | 120 / 분 |
| 설정 (비밀번호, 만료, 최대 다운로드) | 30 / 분 |
| 비밀번호 확인 | 10 / 분 |
| 컬렉션 생성 | 30 / 분 |
| 관리 (준비, 삭제) | 60 / 분 |
| 썸네일 업로드 | 120 / 분 |
| ShareX 업로드 | 20 / 일 |
| 앱 분석 / 오류 | 분당 120 및 60 |
업로드 할당량: 익명 클라이언트는 방문자 토큰당 24시간 기준 100GB과 IP당 24시간 기준 500GB 두 가지 제한이 병행 적용됩니다(IP 제한은 토큰 없는 트래픽과 공유 네트워크를 감지). 둘 중 하나를 초과하면 세부 정보가 포함된 429를 받습니다. 이는 업로드 할당량만 해당하며, 다운로드는 무제한이고 제한되지 않습니다(R2 서명된 URL에서 직접 제공).
업로드
5GB 이상의 파일도 포함한 모든 파일에 대한 3단계 업로드 흐름입니다 (자동으로 멀티파트 처리). 간단한 스크린샷 스타일 업로드가 필요하다면 대신 ShareX를 참고하세요.
/upload/init
60/min
업로드를 시작합니다. 50MB 초과 파일의 경우 응답에 멀티파트 업로드용 part_urls가 포함되며, 그렇지 않으면 단일 url이 포함됩니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
filename | string · required | 원본 파일명. 최대 255자. |
content_type | string · required | MIME 타입. |
size | integer · required | 파일 크기(바이트). 최소 1. |
/upload/parts
120/min
진행 중인 멀티파트 업로드에 대해 추가 파트 URL을 요청합니다. /init에서 반환된 URL이 파트 수보다 적거나 만료되었을 때 사용합니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
upload_id | string · required | /init에서 받은 upload_id. |
part_numbers | array<int> · required | URL을 받을 파트 번호들. |
/upload/complete-multipart
500/min
모든 파트 업로드가 완료되면 R2에서 멀티파트 업로드를 최종 완료합니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
upload_id | string · required | /init에서 받은 upload_id. |
parts | array · required | 각 항목: R2 응답의 { partNumber, etag }. |
/upload/abort
60/min
멀티파트 업로드를 취소하고 R2의 부분 데이터를 정리합니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
upload_id | string · required | 취소할 업로드. |
/upload/confirm
60/min
업로드 완료를 확인합니다. 이때 File 기록을 생성하고 공유 가능한 URL을 반환합니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
filename | string · required | 원본 파일명. |
size | integer · required | 파일 크기(바이트). |
content_type | string · required | MIME 타입. |
r2_key | string · required | /init에서 받은 r2_key. |
collection_id | string · optional | 컬렉션에 첨부. |
crc32 | integer · optional | 무결성 검증을 위한 CRC32 체크섬. |
file_id | string(9) · optional | 이전에 생성된 예약됨 파일 ID를 완료합니다. |
/file/reserve
60/min
바이트가 준비되기 전에 파일 ID와 공유 가능한 URL을 예약합니다. 먼저 링크를 제공하고 나중에 업로드를 완료해야 할 때 유용합니다. 소유권은 방문자 토큰과 IP에 묶여 있습니다. 나중에 /upload/init + /upload/confirm을 사용해 file_id를 전달하여 업로드를 완료하세요.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
filename | string · optional | 플레이스홀더 파일명. 기본값은 "Pending"입니다. |
content_type | string · optional | 플레이스홀더 MIME 타입. |
/upload/init-batch
500/min
웹 업로더에 최적화된 /upload/init의 배치 버전입니다. 한 번의 왕복으로 최대 250개의 파일을 시작합니다.
웹 업로더 내부에서 사용됩니다. 대부분의 클라이언트는 단일 파일 /upload/init을 사용하는 것이 좋습니다.
/upload/confirm-batch
500/min
/upload/confirm의 배치 버전입니다. 한 번의 왕복으로 여러 파일을 확인합니다.
컬렉션
컬렉션은 여러 파일을 하나의 공유 URL(/c/{id}) 아래에 그룹화합니다. 최대 10,000개 파일과 총 25GB까지 지원합니다.
/collection
30/min
새 컬렉션을 만듭니다. 이후 /upload/confirm에서 collection_id를 전달하여 파일을 첨부하세요.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
expected_file_count | integer · optional | 예상된 모든 파일이 확인되면 컬렉션을 자동으로 준비 완료로 표시하는 힌트입니다. |
/collection/{id}/status
120/min
컬렉션 상태를 조회합니다. 예상된 모든 파일이 확인되면 컬렉션을 자동으로 준비 완료로 표시합니다.
/collection/{id}/ready
Owner only
60/min
컬렉션을 다운로드 준비 완료로 표시합니다. 보통 필요하지 않습니다 — expected_file_count에 도달하면 컬렉션이 자동으로 준비 완료됩니다.
/collection/{id}
Owner only
60/min
컬렉션과 모든 파일을 삭제합니다.
/collection/{id}/password
Owner only
30/min
컬렉션에 비밀번호를 설정합니다. 4~100자여야 합니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
password | string · required | 4~100자. |
/collection/{id}/password
Owner only
30/min
컬렉션의 비밀번호를 제거합니다.
/collection/{id}/verify-password
10/min
비밀번호를 확인합니다. 성공 시 200, 비밀번호가 틀리면 401를 반환합니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
password | string · required |
/collection/{id}/expiry
Owner only
30/min
컬렉션 만료일을 변경합니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
days | integer · optional | 지금부터 1~7일. 생략하거나 null로 설정하면 영구(프리미엄 전용)입니다. |
/collection/{id}/max-downloads
Owner only
30/min
다운로드 제한 설정(N회 다운로드 후 삭제). 제한에 도달하면 컬렉션이 자동 삭제됩니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
max_downloads | integer · optional | 1~1000. 현재 다운로드 수보다 커야 합니다. 제한 해제는 null로 설정하세요. |
파일
모든 파일 단위 설정(비밀번호, 만료, 최대 다운로드 수)은 컬렉션 엔드포인트와 동일합니다. 소유자만 사용 가능.
/file/{id}/status
120/min
파일이 아직 업로드 대기 중인지 확인합니다.
/file/{id}
Owner only
60/min
파일을 즉시 삭제합니다.
/file/{id}/thumbnail
Owner only
120/min
비디오 또는 이미지 파일의 썸네일 이미지를 업로드합니다(다운로드 페이지에 사용). 최대 2MB.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
thumbnail | image · required | 멀티파트 업로드. 최대 2MB. |
/file/{id}/password
Owner only
30/min
파일에 비밀번호를 설정합니다. 4~100자여야 합니다.
/file/{id}/password
Owner only
30/min
파일 비밀번호를 제거합니다.
/file/{id}/verify-password
10/min
파일 비밀번호를 확인합니다.
/file/{id}/expiry
Owner only
30/min
파일 만료일을 변경합니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
days | integer · optional | 지금부터 1~7일. 생략하거나 null로 설정하면 영구(프리미엄 전용)입니다. |
/file/{id}/max-downloads
Owner only
30/min
파일 총 다운로드 수를 제한합니다. 제한 도달 시 자동 삭제됩니다.
ShareX 업로드
원샷 업로드 엔드포인트 — 멀티파트 파일을 보내면 공유 가능한 URL을 바로 받습니다. 시작/확인 과정 없이 사용 가능하며, 스크린샷 도구에 이상적입니다. 전체 설정 가이드는 /ko/docs/sharex에서 확인하세요.
데스크탑 인증
Sanctum 토큰을 가진 인증된 클라이언트(예: 데스크탑 앱)용입니다.
/user
Bearer token
인증된 사용자를 반환합니다.
/auth/logout
Bearer token
현재 액세스 토큰을 취소합니다.
기타
/health
헬스 체크입니다. 데이터베이스, R2 스토리지, Redis 캐시에 핑을 보냅니다. 모두 정상일 경우 200, 그렇지 않으면 503을 반환합니다.
/activity
홈페이지 지구본용 실시간 활동 스트림입니다. Cloudflare 엣지에서 캐시됩니다.
/bandwidth/status
60/min
호출자의 현재 업로드 할당량 사용량 — CLI 및 데스크탑 앱에서 남은 용량 표시용입니다. 인증 사용자에 따라 응답 형식이 다릅니다. URL 이름과 달리 업로드 바이트만 추적하며 다운로드는 포함되지 않습니다.
/app-analytics
120/min
CLI 또는 데스크탑 앱에서 사용 이벤트를 제출합니다.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
app | string · required | desktop, cli, 또는 web. |
version | string · optional | 클라이언트 버전. |
event | string · required | 이벤트 이름, 예: upload_complete. |
context | object · optional | 추가 메타데이터. |
/app-errors
60/min
CLI 또는 데스크탑 앱에서 오류 보고서를 제출합니다. 서버 측에서 중복 제거 — 동일 오류는 시간당 최대 10회까지.
요청 본문
| 필드 | 유형 | 설명 |
|---|---|---|
app | string · required | desktop, cli, 또는 web. |
type | string · required | 오류 클래스/유형. |
message | string · required | 오류 메시지. |
stack | string · optional | 스택 트레이스. |
version, os, os_version, arch, context | various · optional | 진단 메타데이터. |