APIUploadWebDAV

API로 동영상 업로드하기: curl, Python, Node.js, WebDAV, FTP

UFOLOAD REST API로 curl, Python, Node.js를 사용해 동영상을 업로드하고 가져오며, 인코딩 완료를 기다리고, 대용량 파일은 WebDAV나 FTP로 올리는 방법.

대시보드를 한 번도 열지 않고도 UFOLOAD에 동영상을 올릴 수 있습니다. REST API는 HTTPS로 업로드를 받고, 서버가 링크에서 파일을 대신 가져올 수도 있으며, 이미 해당 프로토콜을 지원하는 도구를 위해 같은 계정에 WebDAV와 FTP로도 접속할 수 있습니다. 이 가이드에서는 다섯 가지 경로를 모두 실제로 동작하는 명령과 함께 살펴보고, 서버의 응답을 설명하며, 인코딩이 끝날 때까지 기다리는 방법을 보여 줍니다. 아래 엔드포인트는 공개 OpenAPI 명세와 대조해 확인했으며, 전체 레퍼런스는 API 문서에 있습니다.

API 키 만들기

대시보드의 개발자 섹션에서 키를 만드세요. 모든 요청은 이 키를 Authorization 헤더의 Bearer 토큰으로 보냅니다. 키는 생성할 때 한 번만 표시되므로 환경 변수나 시크릿 관리자에 저장하고, 유출되면 대시보드에서 폐기하세요. 같은 키는 WebDAV와 FTP의 비밀번호로도 쓰이며, 로그인 ID는 계정 이메일입니다. 아직 계정이 없다면 무료 계정을 만드세요. 내 요금제에 적용되는 파일 크기 한도와 저장 공간 및 트래픽 할당량은 요금제 페이지에 나와 있습니다.

bash
export UFOLOAD_API_KEY="ufo_..."

curl로 업로드하기

가장 간단한 업로드는 파일을 요청 본문 그대로 보내고, 파일 이름을 X-File-Name 헤더에 넣는 방식입니다. 이름에 공백이나 ASCII가 아닌 문자가 있다면 퍼센트 인코딩(UTF-8)해서 보내세요. 기본적으로 파일은 루트 폴더에 저장되며, 다른 폴더를 지정하려면 ?folder_id=나 X-Folder-Id 헤더를 추가하세요.

본문 그대로 보내기 · bash
curl -X POST "https://ufoload.com/api/v1/files?folder_id=root" \
  -H "Authorization: Bearer $UFOLOAD_API_KEY" \
  -H "X-File-Name: holiday-2026.mp4" \
  -H "Content-Type: video/mp4" \
  --data-binary @holiday-2026.mp4

멀티파트 폼도 사용할 수 있습니다. 파일은 file 필드에 넣고, 폴더는 folder_id 폼 필드로 지정할 수 있습니다:

멀티파트 폼 · bash
curl -X POST "https://ufoload.com/api/v1/files" \
  -H "Authorization: Bearer $UFOLOAD_API_KEY" \
  -F "file=@holiday-2026.mp4"

업로드에 성공하면 파일 객체가 담긴 JSON 본문과 함께 201로 응답합니다. 가장 많이 쓰게 될 필드는 id, public_id(플레이어 주소에 들어가는 짧은 코드), status, duration_ms, max_quality입니다. 서버는 이미 가진 콘텐츠에 공간을 더 쓰지 않습니다. 같은 바이트를 다시 업로드하면 SHA-256 해시로 파일을 대조해 기존 파일과 "duplicate": true를 담아 200으로 응답합니다.

상태의미
201파일이 접수되어 처리 대기열에 등록됨
200같은 콘텐츠가 이미 라이브러리에 있음, duplicate가 true
401키가 없거나 유효하지 않음
404대상 폴더가 존재하지 않음
409저장 공간 부족
413파일이 요금제 허용 크기보다 큼
429요청이 너무 많음, 잠시 후 다시 시도
팁

대용량 업로드에는 일반 API 호출에 적용되는 짧은 요청 시간 제한이 적용되지 않습니다. 서버는 본문이 계속 들어오는 한 받아들이므로 느린 연결 때문에 수 기가바이트 업로드가 끊기지는 않지만, 블록 사이의 멈춤이 너무 길면 리버스 프록시가 연결을 끊을 수 있습니다.

동영상이 준비될 때까지 기다리기

업로드는 절반일 뿐입니다. 업로드 후 파일은 대기열에 들어가 적응형 HLS 래더로 인코딩됩니다(래더가 만들어지는 방식 참고). status는 uploading, queued, processing을 거쳐 ready 또는 failed로 끝나며, 실패한 파일에는 error 메시지가 담깁니다. 몇 초마다 파일 상태를 조회하되, 촘촘한 루프로 호출하지는 마세요. API에는 요청 한도가 있어 429로 응답합니다.

bash
curl "https://ufoload.com/api/v1/files/FILE_ID" \
  -H "Authorization: Bearer $UFOLOAD_API_KEY"

응답은 두 부분으로 되어 있습니다. 메타데이터가 담긴 file, 그리고 마스터 재생 목록(playback), 커버(poster), 마우스 오버 미리보기 스프라이트(sprite), 각 렌디션의 서명된 주소와 expires_at이 담긴 links입니다. 다른 유효 기간이 필요하다면 POST /files/{id}/links로 60초에서 30일까지 유효한 링크를 발급할 수 있으며, 선택적으로 IP 주소나 쿠키에 묶을 수 있습니다.

Python

requests 라이브러리에서는 열린 파일 객체를 넘기면 디스크에서 스트리밍되므로, 큰 동영상도 메모리 사용량이 일정하게 유지됩니다. 아래 함수는 업로드한 뒤 결과를 기다립니다.

python
import os
import time
import urllib.parse

import requests

BASE = "https://ufoload.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['UFOLOAD_API_KEY']}"}


def upload(path, folder_id="root"):
    name = urllib.parse.quote(os.path.basename(path))
    with open(path, "rb") as f:
        r = requests.post(
            f"{BASE}/files",
            params={"folder_id": folder_id},
            data=f,
            headers={**HEADERS, "X-File-Name": name, "Content-Type": "application/octet-stream"},
        )
    r.raise_for_status()
    return r.json()["file"]


def wait_ready(file_id, timeout=3600):
    deadline = time.time() + timeout
    while time.time() < deadline:
        r = requests.get(f"{BASE}/files/{file_id}", headers=HEADERS)
        r.raise_for_status()
        data = r.json()
        status = data["file"]["status"]
        if status == "ready":
            return data
        if status == "failed":
            raise RuntimeError(data["file"].get("error") or "encoding failed")
        time.sleep(5)
    raise TimeoutError("video is still processing")


file = upload("holiday-2026.mp4")
data = wait_ready(file["id"])
print("embed:", f"https://iframe.andromedans.live/e/{file['public_id']}")
print("playlist:", data["links"]["playback"])

Node.js

Node.js 18 이상에는 fetch가 내장되어 있어 의존성이 필요 없습니다. 이 버전은 파일을 메모리로 읽어 들이므로 클립과 짧은 동영상에는 괜찮지만, 수 기가바이트 파일에는 디스크에서 스트리밍하는 curl, WebDAV, FTP를 권장합니다.

js
import { readFile } from 'node:fs/promises'
import { basename } from 'node:path'
import { setTimeout as sleep } from 'node:timers/promises'

const BASE = 'https://ufoload.com/api/v1'
const headers = { Authorization: `Bearer ${process.env.UFOLOAD_API_KEY}` }

async function upload(path) {
  const res = await fetch(`${BASE}/files?folder_id=root`, {
    method: 'POST',
    headers: { ...headers, 'X-File-Name': encodeURIComponent(basename(path)), 'Content-Type': 'application/octet-stream' },
    body: await readFile(path),
  })
  if (!res.ok) throw new Error(`upload failed: ${res.status}`)
  return (await res.json()).file
}

async function waitReady(id) {
  for (;;) {
    const res = await fetch(`${BASE}/files/${id}`, { headers })
    if (!res.ok) throw new Error(`status check failed: ${res.status}`)
    const data = await res.json()
    if (data.file.status === 'ready') return data
    if (data.file.status === 'failed') throw new Error(data.file.error || 'encoding failed')
    await sleep(5000)
  }
}

const file = await upload('holiday-2026.mp4')
const data = await waitReady(file.id)
console.log('embed:', `https://iframe.andromedans.live/e/${file.public_id}`)
console.log('playlist:', data.links.playback)

URL로 가져오기

동영상이 이미 직접 링크로 온라인에 있다면, 내 컴퓨터로 내려받았다가 다시 올리는 대신 서버가 다운로드하게 하세요. 이 호출은 가져오기 작업과 함께 즉시 202를 반환하고, 서버가 파일을 가져온 뒤 인코딩 대기열에 넣습니다. 내부 네트워크, 루프백, 서비스 주소 대역을 가리키는 링크는 거부되며, 활성 가져오기는 최대 10개까지 가능하고, 진행 상황은 GET /files/import로 확인할 수 있습니다.

bash
curl -X POST "https://ufoload.com/api/v1/files/import" \
  -H "Authorization: Bearer $UFOLOAD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/video.mp4", "name": "video.mp4"}'

WebDAV와 FTP

대량 전송이나 API를 호출할 수 없는 도구를 위해 같은 라이브러리를 WebDAV와 FTP로도 이용할 수 있습니다. 로그인 ID는 계정 이메일, 비밀번호는 API 키입니다. 둘 다 디스크에서 스트리밍하므로 아주 큰 파일에 가장 안정적인 방법입니다.

HTTPS를 통한 WebDAV, 포트 443 · bash
curl -u "you@example.com:$UFOLOAD_API_KEY" https://ufoload.com/dav/
curl -u "you@example.com:$UFOLOAD_API_KEY" -T holiday-2026.mp4 https://ufoload.com/dav/holiday-2026.mp4
명시적 TLS를 사용하는 FTP, 포트 21 · bash
curl -u "you@example.com:$UFOLOAD_API_KEY" ftp://ftp.ufoload.com/
curl -u "you@example.com:$UFOLOAD_API_KEY" --ftp-ssl -T holiday-2026.mp4 ftp://ftp.ufoload.com/

API 키가 비밀번호이므로, 클라이언트가 지원한다면 항상 암호화된 방식을 사용하세요. 파일 관리자부터 동기화 도구까지 WebDAV나 FTPS를 지원하는 클라이언트라면 같은 정보로 접속할 수 있습니다. 이렇게 복사한 파일은 라이브러리에 나타나며 다른 업로드와 똑같이 인코딩됩니다.

어떤 경로를 고를까

경로적합한 용도주의할 점
API 업로드사용자를 대신해 업로드하는 애플리케이션과 백엔드클라이언트가 파일 전체를 먼저 읽으면 메모리 사용량
URL로 가져오기이미 공개 직접 링크가 있는 파일직접 http(s) 링크만 가능, 활성 가져오기 10개 제한
WebDAV대용량 파일, 라이브러리를 드라이브로 마운트이메일과 API 키를 인증 정보로 사용
FTP / FTPS기존 도구와 스크립트, 대량 전송명시적 TLS 옵션 사용

동영상 활용하기

상태가 ready가 되면 플레이어 주소는 https://iframe.andromedans.live/e/ 뒤에 public_id를 붙인 것이며, 바로 이것을 iframe에 넣으면 됩니다(긴 id도 동작하며 짧은 주소로 리디렉션됩니다). 마크업과 hls.js 대안은 임베드 가이드에서 보여 줍니다. 도메인 및 국가 규칙으로 재생 위치를 제한할 수 있고, 광고가 제공되는 경우 광고를 켜서 조회로 수익을 낼 수 있습니다. 키는 브라우저 코드에 넣지 말고, 팀원이 떠나면 교체하세요. API는 모든 요금제에서 사용할 수 있으니 오늘 바로 개발을 시작할 수 있습니다.

무료 계정으로 사용해 보세요

동영상을 업로드하고 몇 분 만에 HLS 플레이어와 API 키를 받으세요. 요금제 한도는 요금제 페이지에 나와 있습니다.