이미지, 비디오, 음악 및 음성
텍스트에 사용하는 키로 이미지, 비디오, 음악, 음성을 만들고 녹음을 텍스트로 변환할 수 있으며, 이 모든 것이 동일한 잔액에서 차감됩니다. 모델 표 (또는 ?type=image, ?type=music, ?type=audio)에서 모델을 선택하세요. 각 모델 페이지에는 가격, 유형 및 작동하는 요청 예시가 나와 있습니다.
| 원하는 것 | 경로 | 원본 사진 입력 위치 |
|---|---|---|
| 프롬프트에서 새 이미지 | POST /v1/images/generations |
(없음) |
| 편집된 사진 | POST /v1/images/edits |
image (또는 image_url, input_images, images) |
| 프롬프트에서 비디오 | POST /v1/video/generations |
(없음) |
| 사진에서 시작하는 비디오 | POST /v1/video/generations |
image_url (첫 프레임); end_image_url (마지막 프레임) |
| 참조 사진에서 비디오 | POST /v1/video/generations |
input_images ("role": "reference"와 함께) |
| 사진에 대한 텍스트 답변 | POST /v1/chat/completions |
messages[].content의 image_url 부분 |
| 음악 | POST /v1/music/generations |
(없음) |
| 텍스트에서 음성 | POST /v1/audio/speech |
(없음) |
| 녹음에서 텍스트 | POST /v1/audio/transcriptions |
(없음; 녹음은 file에 입력) |
원본 사진은 https:// 링크, data: URI (data:image/png;base64,iVBORw0…) 또는 PNG, JPEG, WebP의 일반 base64이며, 요청당 최대 8까지 가능합니다. 이미지 경로는 멀티파트 업로드(아래 참조)도 지원합니다. 링크는 공개 https:// 링크여야 합니다. http:// 링크는 거부됩니다. 리디렉션되는 링크(예: https://picsum.photos/640/360)는 최대 5회까지, 그리고 다른 공개 https:// 링크로만 추적되며, 모델은 최종 도착한 링크를 받습니다. 사진으로 연결되지 않거나 사용할 수 없는 곳으로 리디렉션되는 링크는 어떠한 보류나 요금 청구 없이 400 invalid_image_url으로 거부됩니다. 인라인으로 전송된 사진은 요청 크기를 늘립니다. 10 MB 미만으로 유지하거나 링크를 보내세요.
채팅 메시지(messages[].content의 image_url)에서 링크(https:// 또는 http://)는 UberLLM에 의해 열리고 data: URL로 모델에 전송됩니다. 대부분의 비전 모델은 그것만 받기 때문입니다. 각 사진은 최대 20 MB(요청당 40 MB)까지 가능하며, 리디렉션은 최대 5회까지, 공개 주소로만 추적됩니다. Gemini 모델은 링크를 있는 그대로 받습니다. 사진으로 연결되지 않는 링크는 400 invalid_image_url으로 거부되며, 요금은 청구되지 않습니다.
이미지 만들기
이미지는 답변으로 돌아옵니다.
curl https://api.uberllm.dev/v1/images/generations \
-H "Authorization: Bearer $UBERLLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "venice/z-image-turbo", "prompt": "a red apple on a white table", "n": 1, "size": "1024x1024"}'
{ "created": 1792429247, "data": [{ "url": "https://api.uberllm.dev/v1/media/artifacts/<id>/0" }],
"usage": { "cost_usd": 0.0099, "max_cost_usd": 0.0109 } }
usage.cost_usd는 이미지 비용입니다 (X-UberLLM-Cost-USD 헤더에도 있습니다). 가격이 아직 알려지지 않은 드문 답변의 경우 null입니다. 제공업체가 청구한 금액을 지불하며, 이를 위해 보류된 max_cost_usd를 초과하지 않습니다.
response_format는 /v1/images/generations와 /v1/images/edits 모두에 대해 기본적으로 url입니다. 대신 답변 안에 이미지를 받으려면 "response_format": "b64_json"를 보내세요. 모델이 이미지 자체를 반환하면, UberLLM은 이를 24시간 동안 귀하의 계정 파일로 보관하고 해당 링크(https://api.uberllm.dev/v1/files/file_…/content)로 답변합니다. 이 링크는 나중에 편집할 원본 이미지로도 작동합니다. 동일한 키로 URL을 다운로드하세요:
curl -L -o image.png -H "Authorization: Bearer $UBERLLM_API_KEY" \
"https://api.uberllm.dev/v1/media/artifacts/<id>/0"
n는 1에서 10까지입니다.
사진 편집하기
편집 모델(ID는 보통 -edit로 끝납니다)을 사용하고, 원본 사진을 image에 보내세요:
curl https://api.uberllm.dev/v1/images/edits \
-H "Authorization: Bearer $UBERLLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "google/nano-banana-pro-edit", "prompt": "make the sky a sunset",
"image": "https://example.com/skyline.png"}'
동일한 사진은 다음 형식으로 입력할 수 있습니다:
"image": "data:image/png;base64,iVBORw0…""image_url": "https://…""input_images": ["https://…", "https://…"]: 첫 번째는 편집할 사진이고, 나머지는 참조용입니다. 항목은{"url": "…", "role": "reference"}일 수도 있습니다."images": [{"image_url": "https://…"}], OpenAI SDK가 보내는 형식
일반 base64도 작동하며, "input_image"는 "image"으로 읽힙니다.
또는 OpenAI의 이미지 편집처럼 파일을 업로드할 수도 있습니다:
curl https://api.uberllm.dev/v1/images/edits \
-H "Authorization: Bearer $UBERLLM_API_KEY" \
-F model=google/nano-banana-pro-edit -F prompt="make the sky a sunset" \
-F [email protected]
원본 사진이 없는 편집 요청은 400 image_required 오류와 함께 거부됩니다. 마스크(인페인팅)는 지원되지 않습니다.
사진 한 번만 업로드하세요
/v1/files에 사진을 업로드하고, 매번 요청에 보낼 필요 없이 24시간 동안 원하는 만큼 많은 요청에 사용하세요:
curl https://api.uberllm.dev/v1/files \
-H "Authorization: Bearer $UBERLLM_API_KEY" \
-F [email protected]
{ "id": "file_3f9c…", "object": "file", "bytes": 482113, "content_type": "image/png",
"filename": "skyline.png", "created_at": 1792540800, "expires_at": 1792627200,
"url": "https://api.uberllm.dev/v1/files/file_3f9c…/content" }
그런 다음 ID 또는 url을(를) 원본 사진이 들어가는 모든 곳에 넣으세요: "image": "file_3f9c…", "image": {"file_id": "file_3f9c…"}, "image_url": "file_3f9c…", input_images의 항목, 또는 비디오의 시작 프레임. 귀하의 계정만 해당 파일을 사용할 수 있습니다.
- PNG, JPEG, WebP, GIF, HEIC 또는 AVIF, 각 파일당 최대 10MB, 계정당 한 번에 최대 500개까지 보관됩니다.
- 24시간 동안 보관된 후 삭제됩니다.
GET /v1/files/{id}은(는) 하나를 설명하고,GET /v1/files/{id}/content은(는) 다운로드하며,DELETE /v1/files/{id}은(는) 지금 삭제합니다.
비디오 만들기
비디오는 1분 이상 걸리므로, 시작하고, 확인하고, 다운로드하는 작업입니다.
1. 시작하기
curl https://api.uberllm.dev/v1/video/generations \
-H "Authorization: Bearer $UBERLLM_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"model": "fal-ai/vidu/q3/text-to-video/turbo", "prompt": "a red ball bouncing on green grass",
"duration_seconds": 5, "models": ["fal-ai/kling-video/v3/standard/text-to-video"]}'
models은 선택 사항입니다. 첫 번째 모델에 현재 무료 제공자가 없을 때만 백업 모델이 순서대로 시도되므로, 바쁜 순간에도 요청이 실패하지 않습니다 (대체 모델] 참조). 위 비디오는 약 1분 정도 걸리며 약 $0.33의 비용이 듭니다.
사진으로 시작하려면, 이미지-투-비디오 모델을 사용하고 image_url을 추가하세요:
-d '{"model": "bytedance/seedance-2-0-image-to-video", "prompt": "slow push-in as the waves roll",
"image_url": "https://example.com/first-frame.png", "duration_seconds": 5}'
두 장의 사진을 혼합하는 모델은 end_image_url (마지막 프레임)도 받습니다.
텍스트만으로는 비디오를 만들 수 없는 이미지-투-비디오 또는 레퍼런스-투-비디오 모델은 요청에 사진이 없을 경우, 요금이 부과되기 전에 400 image_required으로 거부됩니다. 레퍼런스-투-비디오 모델은 input_images에 있는 사진을 사용합니다:
-d '{"model": "pixverse/pixverse-c1-reference-to-video", "prompt": "the cat walks across the room",
"input_images": [{"url": "https://example.com/cat.png", "role": "reference"}],
"aspect_ratio": "16:9", "duration_seconds": 5}'
모델이 제공하는 다른 필드: resolution (480p, 720p, 1080p…), aspect_ratio (16:9, 9:16, 1:1…) 및 audio (true / false; 사운드 설정이 없는 모델에는 이 설정이 전송되지 않으며, 항상 하던 대로 클립을 만듭니다). 레퍼런스-투-비디오 모델은 모양이 필요하므로, aspect_ratio을 비워두면 16:9로 전송됩니다 (또는 16:9를 만들지 않는 경우 모델의 첫 번째 모양으로). 모델의 schema에 해당 기본값이 표시됩니다. 각 모델의 선택 사항은 GET /v1/models/<model id>에 나열되어 있습니다 (각 모델의 옵션] 참조).
각 모델은 특정 클립 길이, 해상도 및 모양만 만듭니다. 모델이 만들 수 없는 것에 대한 요청은, 요금이 부과되기 전에 모델이 만들 수 있는 것들을 나열하는 메시지와 함께 거부됩니다.
HTTP 202:
{
"id": "6f1c…",
"object": "media.job",
"kind": "video",
"status": "queued",
"model": "fal-ai/vidu/q3/text-to-video/turbo",
"estimated_cost_usd": 0.32725,
"estimated_cost_usdc": "327250",
"max_cost_usd": 0.359975,
"max_cost_usdc": "359975",
"poll_url": "/v1/video/generations/6f1c…",
"cancel_url": "/v1/video/generations/6f1c…"
}
model은 작업을 수행한 모델입니다 (첫 번째 모델이 실패했을 때 models의 백업 모델). _usdc로 끝나는 비용은 100만분의 1달러 단위입니다 (327250 = $0.33). estimated_cost_usd은 요청한 항목의 정가입니다. validate와 POST /v1/quote은 cost_usd와 동일한 숫자로 응답합니다. 이는 현재 모델 가격에 초 (요청된 해상도 기준), 이미지 또는 기타 단위를 곱한 값입니다. 작업은 제공자가 청구한 금액으로 청구되며, 이는 더 많거나 적을 수 있습니다. max_cost_usd는 작업에 대해 잔액에서 보류되는 금액입니다. 작업이 실행 중일 때와 완료된 후에도 동일한 금액이며, 작업에 청구될 수 있는 최대 금액입니다. second당 가격이 책정된 비디오 모델은 클립의 초당 요금이 청구됩니다. job당 가격이 책정된 모델은 비디오당 해당 비용이 듭니다.
2. 확인하기 5–10초마다:
curl -H "Authorization: Bearer $UBERLLM_API_KEY" \
https://api.uberllm.dev/v1/video/generations/<job id>
작업 실행 중에는 HTTP 202, 작업 완료 시에는 HTTP 200:
{
"id": "6f1c…",
"status": "succeeded",
"results": [{ "artifact_index": 0, "url": "https://api.uberllm.dev/v1/media/artifacts/6f1c…/0",
"content_type": "video/mp4", "duration_seconds": 5 }],
"usage": { "cost_usdc": "40000", "cost_usd": 0.04 }
}
모델은 파일이 준비된 직후, 일반적으로 30초 이내에 작업의 정확한 요금을 보고합니다. 그때까지 succeeded 작업은 "usage": { "cost_usd": null, "cost_pending": true }를 표시합니다. 몇 초 후에 다시 요청하세요. 만약 30분 이내에 요금이 나오지 않으면, 작업은 정가 (estimated_cost_usd)로 청구되며 usage.cost_note에 그렇게 표시됩니다.
3. 다운로드하기
curl -L -o video.mp4 -H "Authorization: Bearer $UBERLLM_API_KEY" \
https://api.uberllm.dev/v1/media/artifacts/<job id>/0
더 이상 필요 없는 작업을 중지하려면 DELETE /v1/video/generations/<job id>를 요청하세요. 저희는 제공자에게 중지를 요청합니다. 이미 만들어진 작업은 평소와 같이 청구되며, 중지된 작업은 canceled으로 끝나며 비용이 들지 않습니다.
Fal 비디오 모델
ID가 fal-ai/로 시작하는 모델은 Fal에서 Fal 자체 가격보다 저렴하게 실행됩니다. 현재 마켓플레이스에서 가장 저렴한 Fal 판매자의 할인 가격을 제외한 Fal 가격을 지불합니다 (2026년 10월 30일에서는 15% 할인; 해당 판매자가 판매할 때마다 25% 할인). 가격은 요청하는 내용(초당 해상도 요율, 클립에 사운드 유무)에 따라 결정되므로, 작업 시작 시 비용을 알 수 있으며 estimated_cost_usd가 정확히 청구됩니다. 실패한 작업에는 비용이 청구되지 않습니다. 작업 중단은 최선을 다하지만, Fal이 이미 클립을 생성했다면 비용이 청구됩니다.
curl https://api.uberllm.dev/v1/video/generations \
-H "Authorization: Bearer $UBERLLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "fal-ai/wan/v2.7/text-to-video", "prompt": "a woman twirls at a garden party at night",
"duration_seconds": 15, "resolution": "720p", "aspect_ratio": "9:16"}'
Fal 자체의 초당 가격 (귀하의 가격은 실시간 할인을 제외한 가격입니다; 각 모델 페이지 GET /v1/models 및 POST /v1/quote에서 현재 정확한 가격을 확인할 수 있습니다):
| 모델 | 길이 (초) | Fal의 초당 가격, 시작 |
|---|---|---|
fal-ai/wan/v2.7/text-to-video, …/image-to-video |
2–15 | 720p $0.10 · 1080p $0.15 |
fal-ai/kling-video/v3/standard/text-to-video, …/image-to-video |
3–15 | $0.084 · 사운드 포함 $0.126 |
fal-ai/kling-video/v3/pro/text-to-video, …/image-to-video |
3–15 | $0.112 · 사운드 포함 $0.168 |
fal-ai/kling-video/o3/standard/text-to-video, …/image-to-video |
3–15 | $0.084 · 사운드 포함 $0.112 |
fal-ai/kling-video/v2.6/pro/text-to-video, …/image-to-video |
5, 10 | $0.07 · 사운드 포함 $0.14 |
fal-ai/veo3.1/fast, fal-ai/veo3.1/fast/image-to-video |
4, 6, 8 | 720p/1080p $0.10 · 사운드 포함 $0.15 · 4k $0.30 |
fal-ai/veo3.1, fal-ai/veo3.1/image-to-video |
4, 6, 8 | 720p/1080p $0.20 · 사운드 포함 $0.40 · 4k $0.40 |
fal-ai/veo3.1/lite |
4, 6, 8 | 720p $0.03 · 사운드 포함 $0.05 · 1080p $0.05 |
fal-ai/ltx-2.3/text-to-video/fast, …/image-to-video/fast |
6, 8, 10 | 1080p $0.06 · 1440p $0.12 · 2160p $0.24 |
fal-ai/ltx-2.3/text-to-video |
6, 8, 10 | 1080p $0.08 |
fal-ai/minimax/hailuo-02/standard/text-to-video, …/image-to-video |
6, 10 | 768P $0.045 · 512P (이미지) $0.017 |
fal-ai/vidu/q3/text-to-video/turbo, …/image-to-video/turbo |
1–16 | 360p/540p $0.035 · 720p/1080p $0.077 |
fal-ai/vidu/q3/text-to-video, …/image-to-video |
1–16 | 360p/540p $0.07 · 720p/1080p $0.154 |
각 가격은 Fal 자체 가격입니다; 작업 시작 시 할인이 적용됩니다. 가장 저렴한 판매자가 작업을 거부하면, 더 비싼 판매자가 작업을 수행하며 해당 판매자의 가격으로 작업이 청구됩니다. 이 경우 응답 시 estimated_cost_usd를 초과하지 않습니다.
일부 모델은 판매자 할인에 명시된 것보다 적은 비용이 듭니다. 매 6시간마다 지난 7일 동안 마켓플레이스가 각 모델에 대해 청구한 금액을 동일한 작업에 대한 Fal의 가격과 비교합니다. 해당 기간 동안 최소 20개의 작업을 수행한 모델은, 더 낮은 경우 실제 점유율에 5%를 더한 가격으로 책정됩니다. 모델 페이지 /v1/models와 청구서 모두 동일한 가격을 사용합니다. 해당 수치가 3일보다 오래된 경우, 판매자 할인이 다시 적용됩니다.
다음 필드는 당사에서 제공합니다: duration_seconds, resolution, aspect_ratio, audio 및 image_url (또는 input_images). Fal 자체 표기법 (duration, generate_audio, start_image_url)도 작동합니다. Kling, Veo 및 Kling 2.6은 "audio": false을 보내지 않는 한 사운드를 추가합니다.
작업 상태
status |
HTTP | 의미 |
|---|---|---|
queued |
202 | 승인됨, 모델이 시작하기를 기다리는 중 |
running |
202 | 제작 중; 모델이 보고하면 progress이 0에서 1으로 변경됩니다 |
succeeded |
200 | 완료됨; results[].url 다운로드 |
failed |
200 | 제작되지 않음. error.message은 이유를 알려주고; error.retryable은 다시 시도할 수 있는지 알려줍니다 |
canceled |
200 | 제작되기 전에 중단됨 |
expired |
200 | 시간 내에 완료되지 않음 |
이 여섯 가지가 유일한 값입니다. failed, canceled, expired은 비용이 들지 않습니다. DELETE는 중단 요청이지 약속이 아닙니다: 공급자가 어쨌든 완료하는 작업은 succeeded로 끝나고 요금이 청구됩니다.
바쁜 순간에는 자동으로 재시도됩니다. 비디오를 제작할 수 있는 공급자가 없거나, 현재 너무 바쁠 때, UberLLM은 10분 이내에 최대 두 번까지 작업을 자동으로 다시 시작합니다. 동일한 job id와 최대 예상 비용을 유지합니다. 작업은 단지 조금 더 오래 걸릴 뿐입니다. 모든 시도가 실패했을 때만 failed을 보게 되며, 실패한 작업에는 비용이 들지 않습니다.
대기 중. callback_url을 보내주시면 작업이 언제 끝나는지 알려드리거나 ( Callbacks 참조), 5–10초마다 poll URL을 확인하세요. 대부분의 비디오는 1–5분 정도 걸리며; 일부 길거나 4K 작업은 더 오래 걸립니다. 요금 정산을 위해 계속 확인할 필요는 없습니다: 아무도 확인하지 않는 작업도 UberLLM에 의해 완료되고 청구(또는 환불)되며, Dashboard → Activity에 표시됩니다.
콜백
비디오 또는 음악 작업에 callback_url를 추가하세요: 공개 호스트의 https:// 링크입니다. 작업이 완전히 종료되면 UberLLM은 작업에서 GET가 반환하는 것과 동일한 JSON과 함께 해당 링크로 POST를 보냅니다.
{ "model": "kling/kling-o3", "prompt": "a red ball bouncing", "duration_seconds": 5,
"callback_url": "https://your-app.example/uberllm/jobs" }
- 시기. 작업이 종료되고 요금이 확정되면 한 번:
usage.cost_usd가 설정된succeeded(절대cost_pending아님), 또는failed,canceled또는expired(비용 0). 비용이 도착할 때 다시 전송되지 않습니다. 비용 도착 후에만 전송되기 때문입니다.output_upload_url의 경우에도 업로드가 완료된 후에 콜백이 오므로output_upload.status는 이미delivered또는failed입니다. - 헤더.
Content-Type: application/json,UberLLM-Event: job.succeeded(또는job.failed,job.canceled,job.expired),UberLLM-Event-Id: <job id>:<status>및UberLLM-Signature: t=<unix seconds>,v1=<hex>. - 재시도. 15초 이내에 2xx로 응답하세요. 다른 응답이거나 응답이 없는 경우, 30초, 2분, 10분, 30분, 2시간 후에 다시 시도한 다음 포기합니다. 언제든지 작업을 폴링할 수 있습니다.
- 반복. 메시지가 두 번 이상 도착할 수 있습니다 (예: 응답이 손실된 경우). 이벤트 ID는 동일하게 유지되므로 이미 처리한 메시지는 삭제하세요.
- 상태. 작업 진행 상황은 다음과 같습니다:
"callback": { "status": "delivered", "attempts": 1, "http_status": 200, "delivered_at": 1792540990 }.status은pending,delivered또는failed입니다 (error은 일반 텍스트로 표시됨). - 링크는 공개 호스트에
https://여야 하며, 사용자 이름이나 비밀번호를 포함해서는 안 됩니다. 이 링크는 다시 표시되지 않으며 콜백이 끝나면 삭제됩니다.webhook_url는 동일한 필드로 읽힙니다. 이미지와 음성은 이를 사용하지 않습니다. 응답 자체로 돌아옵니다.
서명 확인
모든 메시지는 계정의 웹훅 비밀로 서명됩니다. 대시보드 → API keys → Webhook signing secret]에서 찾을 수 있습니다. 처음 열 때 생성되며, Replace secret를 통해 즉시 변경할 수 있습니다.
v1은 전체 비밀 (whsec_…)로 키가 지정된 <t>.<raw body>의 헥스 HMAC-SHA256입니다. 수신한 원시 바이트 (JSON 파싱 전)에 대해 계산하고, 상수 시간으로 비교하며, 5분 이상 된 t는 거부하세요.
Node.js (Express):
import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.UBERLLM_WEBHOOK_SECRET; // whsec_…
app.post("/uberllm/jobs", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("UberLLM-Signature") || "";
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
const expected = crypto.createHmac("sha256", SECRET)
.update(`${parts.t}.`).update(req.body).digest("hex");
const ok = parts.v1 && parts.v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected)) &&
Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
if (!ok) return res.status(400).send("bad signature");
const job = JSON.parse(req.body);
// Drop a repeat: req.get("UberLLM-Event-Id") is the same each time.
console.log(job.id, job.status, job.usage?.cost_usd);
res.sendStatus(204);
});
Python (Flask):
import hashlib, hmac, os, time
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["UBERLLM_WEBHOOK_SECRET"].encode() # whsec_…
@app.post("/uberllm/jobs")
def uberllm_job():
raw = request.get_data() # the raw bytes, before any JSON parsing
parts = dict(p.split("=", 1) for p in request.headers.get("UberLLM-Signature", "").split(",") if "=" in p)
expected = hmac.new(SECRET, parts.get("t", "").encode() + b"." + raw, hashlib.sha256).hexdigest()
if not hmac.compare_digest(parts.get("v1", ""), expected) or abs(time.time() - int(parts.get("t", "0"))) > 300:
abort(400)
job = request.get_json()
# Drop a repeat: request.headers["UberLLM-Event-Id"] is the same each time.
print(job["id"], job["status"], job.get("usage", {}).get("cost_usd"))
return "", 204
웹훅으로 알림
알림 이메일은 웹훅으로도 전송될 수 있습니다. 대시보드 → Credits → For developers: also send alerts to a webhook]에서 링크를 설정하거나, PUT /api/v1/billing/alerts {"alerts_webhook_url": "https://…"} (null은 끄기)를 설정하세요. 메시지는 콜백과 동일한 방식으로 서명되고, 재시도되며, 식별됩니다. 본문은 다음과 같습니다.
{ "id": "evt_…", "object": "event", "type": "balance.low", "created": 1792540990,
"data": { "balance_usd": 4.2, "threshold_usd": 5, "message": "Your balance is $4.20, below the $5.00 you set. Requests stop once it runs out.",
"add_credits_url": "https://uberllm.dev/dashboard/credits" } }
balance.low: 잔액이 저잔액 이메일에 설정한 금액 미만으로 떨어졌습니다. 금액 미만으로 떨어질 때마다 한 번 전송됩니다. 금액을 설정하기 전까지는 아무것도 전송되지 않습니다.hold.not_released: 작업이 종료된 후 15분 이상 작업에 할당된 금액이 계속 보류되었습니다.data.jobs에 해당 목록이 있으며 (id,kind,model,ended_at,held_usd),data.held_usd은 총액입니다. 이 금액은 여전히 귀하의 것이며, 저희 팀에 통보되었습니다.
파일 보관 기간
결과가 생성된 직후 다운로드하세요:
- 동영상 및 음악 파일은 작업이 끝난 후 약 3시간 동안 보관됩니다.
/v1/media/artifacts/…로 연결되는 이미지 링크는 약 15분 동안 보관됩니다./v1/files/…로 연결되는 이미지 링크는 24시간 동안 보관됩니다. 답변 내부에 그림을 포함하여 직접 보관하려면"response_format": "b64_json"를 요청하세요./v1/files에 업로드한 사진은 24시간 동안 보관됩니다.
그 이후에는 다운로드 시 404 artifact_expired으로 응답합니다.
결과를 자체 스토리지로 전송
동영상 또는 음악 작업에 output_upload_url을 추가하세요: presigned S3, R2 또는 Google Cloud Storage 업로드 링크와 같이 HTTP PUT을 허용하는 https:// 링크입니다. 작업이 성공하면 UberLLM은 해당 파일의 콘텐츠 유형과 함께 파일을 그곳에 업로드합니다. 여러 파일을 생성하는 작업의 경우, 파일당 하나의 링크를 순서대로 output_upload_urls로 보내세요 (최대 4개).
{ "model": "kling/kling-o3", "prompt": "a red ball bouncing", "duration_seconds": 5,
"output_upload_url": "https://my-bucket.s3.amazonaws.com/ball.mp4?X-Amz-Signature=…" }
그러면 작업 상태에 output_upload이(가) 포함됩니다:
"output_upload": { "status": "delivered", "attempts": 1, "delivered_at": 1792540990,
"files": [{ "artifact_index": 0, "http_status": 200, "bytes": 5242880 }] }
status은(는) 업로드가 완료될 때까지pending입니다. 그 후delivered또는failed(error는 일반적인 단어로 표시됨)가 됩니다.- 업로드 실패 시 30초, 2, 10, 30분 후에 다시 시도됩니다. 그 후
failed으로 표시됩니다. 파일이 보관되는 동안에는results[].url에서 계속 다운로드할 수 있습니다. 링크는 최소 한 시간 동안 유효해야 합니다. - 링크는 공용 호스트에서
https://이어야 하며, 사용자 이름이나 비밀번호가 포함되어서는 안 됩니다. 이 링크는 다시 표시되지 않으며, 업로드가 완료되면 삭제됩니다. - 이미지는 이를 사용하지 않습니다. 이미지는 답변 자체에 포함되어 돌아옵니다.
음악
/v1/music/generations에서 같은 세 단계입니다. curl -OJ는 저희가 보내는 파일 이름으로 트랙을 저장합니다.
음성
텍스트를 입력하면 오디오 파일이 답변으로 돌아옵니다.
curl https://api.uberllm.dev/v1/audio/speech \
-H "Authorization: Bearer $UBERLLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "x-ai/tts-xai-v1", "input": "Hello from UberLLM."}' \
-o speech.mp3
voice, response_format (예를 들어 mp3 또는 wav) 및 speed를 보낼 수도 있습니다.
각 모델에는 고유한 음성이 있습니다 (GET /v1/models/{id}에 목록이 있습니다). best-price:speech 또는 fastest:speech을 사용하면 어떤 모델이 사용될지 미리 알 수 없으므로, 음성이 모델에 맞춰집니다. 모델이 가지고 있는 음성은 유지되며, OpenAI의 이름은 모델이 해당 음성을 가지고 있는 경우 모델의 일치하는 음성에 매핑됩니다 (alloy → af_alloy). 다른 음성이거나 음성이 없는 경우, 모델의 첫 번째 음성이 사용됩니다. 모델 이름을 지정하면, 사용자의 음성은 그대로 전송됩니다.
input의 1K자 단위로 요금이 청구됩니다. 답변은 오디오 파일이며, 해당 X-UberLLM-Cost-USD 헤더에는 비용이 명시되어 있고, X-Request-Id은 활동(Activity)에 나열된 요청 ID입니다. "validate": true, max_cost, metadata, models 및 provider.max_price은 이미지와 동일하게 작동합니다 (요금 안내] 참조).
녹음을 텍스트로 변환하기
녹음을 file 및 model을 포함한 양식으로 보내세요:
curl https://api.uberllm.dev/v1/audio/transcriptions \
-H "Authorization: Bearer $UBERLLM_API_KEY" \
-F model=venice/whisper-large-v3 \
-F [email protected]
{ "text": "Hello from UberLLM.", "duration": 4.2,
"usage": { "type": "duration", "seconds": 5, "cost_usd": 0.00055, "max_cost_usd": 0.00726 } }
비용은 usage.cost_usd입니다 (또한 X-UberLLM-Cost-USD 헤더에 있으며, text, srt, vtt 답변을 위한 유일한 장소입니다). 저희 자체 필드도 양식에 포함되며, 모델로 전송되지 않습니다: -F max_cost=0.10, -F "metadata[project]=podcast", -F validate=true.
또한 language, prompt, temperature, response_format를 보낼 수 있습니다: json (기본값), 또는 text, srt, vtt를 통해 일반 텍스트를 받을 수 있습니다. 오디오 1분당 요금이 청구됩니다. 파일은 최대 40 MB까지 가능합니다. 형식(mp3, wav, ogg, flac, m4a/mp4, webm, aac)은 파일 이름이 아닌 녹음 자체에서 읽히므로, tmp123.out이라는 이름의 업로드도 작동합니다.
OpenAI SDK로
from openai import OpenAI
client = OpenAI(base_url="https://api.uberllm.dev/v1", api_key="<your UberLLM key>")
speech = client.audio.speech.create(model="x-ai/tts-xai-v1", voice="eve", input="Hello from UberLLM.")
speech.write_to_file("speech.mp3")
with open("speech.mp3", "rb") as f:
text = client.audio.transcriptions.create(model="venice/whisper-large-v3", file=f)
print(text.text)
지불하는 금액
- 생성된 결과물 가격: 공급자가 청구한 금액이며, UberLLM 수수료는 없습니다. 이미지 또는 전사(transcription) 답변과 완료된 작업은
usage.cost_usd(미국 달러)로 청구됩니다. 무언가를 생성한 모든 답변은X-UberLLM-Cost-USDresponse header에도 포함됩니다 (음성(speech)의 경우, 답변이 오디오 파일이므로 header가 유일한 위치입니다). 이 내역은 대시보드 → 활동에서 확인할 수 있습니다. 나머지 보류 금액은 반환됩니다. failed,canceled또는expired된 작업, 또는 실패한 이미지, 음성(speech), 전사(transcription) 요청에 대해서는 아무것도 청구되지 않습니다.- 요청하신 내용을 정확히 생성하는 가장 저렴한 판매자. 많은 이미지 및 비디오 모델은 여러 판매자를 가집니다. 각 요청은 설정에 따라 생성할 수 있는 가장 저렴한 판매자에게 전달되며, 해당 판매자가 처리할 수 없는 경우 다른 판매자에게 전달됩니다. 모델 목록과 각 모델 페이지에는 현재 가장 저렴한 판매자의 가격이 표시됩니다.
GET /v1/balance(아래 참조)에서 잔액과 보류 중인 금액을 확인하세요.
사용 전 가격 확인
모든 이미지, 비디오, 음악 또는 음성(speech) 요청에 "validate": true를 추가하세요 (전사(transcription)의 경우, 녹음 파일과 함께 validate=true를 form field로 보내세요). 요청은 실제처럼 확인되지만 (모델, 옵션, 원본 이미지), 아무것도 생성되지 않고 아무것도 청구되지 않습니다. HTTP 200는 명시된 가격 (cost_usd, 모델 페이지에 표시된 가격; 실제로는 공급자가 청구한 금액을 지불하며, 이는 다를 수 있습니다)과 실행 중 보류되는 금액 (max_cost_usd, 최대 청구 금액)을 알려줍니다.
{ "object": "quote", "model": "bytedance/seedance-2-0-image-to-video", "kind": "video",
"valid": true, "cost_usd": 0.2117, "max_cost_usd": 0.4235, "unit": "second", "units": 5, "duration_seconds": 5,
"note": "Nothing was charged. …" }
모델 판매자가 누락된 설정 (예: 비디오 참조 모델이 aspect_ratio를 필요로 하는 경우)을 필요로 한다면, 기본값은 모델의 schema와 견적에 defaults_applied로 표시됩니다 (예: "defaults_applied": {"aspect_ratio": "16:9"}).
거부될 요청은 동일한 방식으로 이유와 함께 거부됩니다.
15분 동안 가격 유지
POST /v1/quote는 이미지, 비디오, 음악 또는 음성(speech) 요청과 동일한 body를 사용하며, 명시된 비용 (cost_usd), 실행 중 보류되는 금액 (max_cost_usd, 최대 청구 금액) 및 quote_id를 반환합니다 (전사(transcription)의 경우 model와 duration_seconds를 보내세요; 전사(transcription) 자체는 quote_id를 사용하지 않으므로 max_cost를 사용하여 제한하세요).
curl https://api.uberllm.dev/v1/quote \
-H "Authorization: Bearer $UBERLLM_API_KEY" -H "Content-Type: application/json" \
-d '{"model": "kling/kling-o3", "prompt": "a red ball bouncing", "duration_seconds": 5}'
{ "object": "quote", "id": "6f1c…", "quote_id": "6f1c…", "model": "kling/kling-o3",
"kind": "video", "cost_usd": 0.225, "max_cost_usd": 0.495, "unit": "job", "units": 1,
"expires_at": 1792541700, "note": "Nothing was charged. …" }
15분 이내에 "quote_id": "6f1c…"와 함께 동일한 요청을 보내면, 공급자가 청구한 금액 (최대 max_cost_usd)이 청구됩니다. 시작 시 보류되어야 할 금액이 max_cost_usd를 초과하면, 무료로 취소됩니다. 견적 자체에 대해서는 아무것도 청구되거나 보류되지 않습니다.
- 하나의 견적은 하나의 요청을 시작합니다. 다시 사용하면
409 quote_used가 반환됩니다. 모델에 도달하지 못한 작업은 견적을 반환합니다. - 요청은 동일한 내용을 요구해야 합니다: 동일한 모델 및 동일한 설정 (prompt, size, clip length, source pictures …). 그 외의 모든 것은
400 quote_mismatch로 거부됩니다.max_cost,metadata및output_upload_url는 다를 수 있습니다. - 15분 후에는
400 quote_expired가 반환됩니다. 채팅 모델은 token당 청구되며 견적이 없습니다:provider.max_price로 제한하세요.
대체 모델 및 가격 상한선
"models": ["model-b", "model-c"]는 첫 번째 모델을 지금 바로 제공할 수 없거나 (no_available_provider) provider.max_price를 초과할 때 순서대로 시도할 모델의 이름을 지정합니다. 다른 모든 거부는 즉시 응답됩니다. 답변의 model는 결과물을 생성한 모델의 이름을 지정합니다 (음성(speech) 답변은 오디오 파일 자체입니다: 활동에서 해당 모델을 보여줍니다). quote_id가 포함된 요청은 models를 사용하지 않으며, 전사(transcription)는 둘 다 사용하지 않습니다.
"provider": {"max_price": 0.05}는 한 단위 (모델의 가격 책정 unit: 이미지, 초, 메가픽셀, 분, 1K 문자 또는 요청)가 미국 달러로 청구될 수 있는 최대 금액입니다. 이를 초과하는 모델은 400 max_price_exceeded로 거부되며, 요청은 해당 단위의 max_price배를 초과하여 청구되지 않습니다. 다른 provider 옵션은 400 unsupported_routing_option로 거부됩니다. 미디어 요청의 판매자 선택은 요청별로 조종할 수 없기 때문입니다.
"model": "best-price:image" (또는 image-edit, text-to-video, image-to-video, music, speech, transcription)는 작업에 가장 저렴한 활성 모델을 선택합니다. fastest:는 측정된 것 중 가장 빠른 모델을 선택합니다. 모델 별칭를 참조하세요.
태그
"metadata": {"project": "spring-ads"} (최대 16개의 텍스트 값)는 작업과 함께 저장되고, 상태에 따라 반환되며, 활동 및 CSV 내보내기에서 표시되고, 모델로 전송되지 않습니다. 전사(transcription)의 경우, form field로 보내세요: -F "metadata[project]=spring-ads". 태그를 참조하세요.
상한선 설정하기
모든 이미지, 비디오, 음악 또는 음성(speech) 요청에 "max_cost" (미국 달러, 예: 0.50)를 보내세요 (전사(transcription)의 경우 form field). 비용이 이를 초과할 수 있다면, 400 max_cost_too_low로 거부되며 아무것도 청구되지 않습니다. 비디오 또는 음악 작업의 경우 정확한 상한선은 작업 시작 시 설정됩니다. 만약 작업이 max_cost를 초과하면, 무료로 취소됩니다. "validate": true를 사용하면 견적에 within_max_cost가 추가됩니다.
두 번 결제 없이 재시도
비디오 또는 음악 작업을 시작할 때 Idempotency-Key header (UUID와 같이 최대 255자까지의 고유한 문자열)를 보내세요. 연결이 끊어지고 24시간 이내에 동일한 키로 동일한 요청을 다시 보내면, 두 번째 작업 대신 동일한 작업을 다시 받게 됩니다. 다른 요청과 함께 동일한 키를 사용하면 409 idempotency_key_reused로 거부됩니다. 이미지, 음성(speech) 및 전사(transcription) 요청은 키를 사용하지 않습니다: 실패한 요청은 청구되지 않았으므로 다시 보내세요.
잔액
curl -H "Authorization: Bearer $UBERLLM_API_KEY" https://api.uberllm.dev/v1/balance
{ "balance_usd": 12.40, "held_usd": 0.35, "available_usd": 12.05 }
held_usd는 아직 실행 중인 요청을 위해 할당되었습니다. 해당 요청이 완료되면 (실제 비용을 제외하고) 다시 돌아옵니다. available_usd는 새로운 요청에 사용할 수 있습니다.
각 모델의 옵션
GET /v1/models?type=image (또는 video, music, speech, transcription, 이 둘 모두에 대한 audio, chat, all; 쉼표로 여러 개 연결됨; type가 없으면 목록은 채팅 모델만 표시됩니다)는 현재 호출할 수 있는 모델을 나열하며, 각 모델은 해당 type, 그것을 보낼 endpoints, 그리고 해당 pricing를 포함합니다. GET /v1/models/<model id>은 하나의 모델을 제공하며, 미디어 모델의 경우 클립 길이, 해상도, 화면 비율 및 허용하는 크기, 그리고 필요한 원본 이미지를 포함하는 요청 본문의 JSON Schema인 parameters 객체를 제공합니다.
curl -H "Authorization: Bearer $UBERLLM_API_KEY" \
https://api.uberllm.dev/v1/models/pixverse/pixverse-c1-reference-to-video
pricing는 usd (현재 unit 하나가 가장 비싼 가격)과 list_usd (모델 제작사 자체 가격)을 가집니다. 채팅 모델은 input_usd, output_usd 그리고 1M tokens당 list_ 가격을 가집니다.
오류
| HTTP | 코드 | 의미 |
|---|---|---|
| 400 | wrong_endpoint |
예를 들어, 이미지 모델을 /v1/video/generations로 보냈거나, 채팅 모델을 이미지 경로로 보냈거나, 음성 모델을 /v1/audio/transcriptions로 보낸 경우; 메시지에 올바른 경로가 표시됩니다. 요금은 청구되지 않으며, 활동 내역에 거부됨으로 표시됩니다. |
| 400 | invalid_request |
요청이 잘못되었습니다 (메시지에 이유가 나와 있습니다. 예를 들어, 모델이 제공하지 않는 기간이거나 원본 사진이 없는 경우). |
| 400 | image_required |
원본 사진이 없는 편집, 또는 이미지-비디오 또는 참조-비디오 모델 요청입니다. |
| 400 | max_cost_too_low |
max_cost보다 비용이 더 많이 들 수 있습니다. 요금은 청구되지 않았습니다. |
| 409 | idempotency_key_reused |
해당 Idempotency-Key가 다른 요청에 사용되었습니다. |
| 400 | quote_mismatch / quote_expired |
요청이 견적과 일치하지 않거나, 견적이 15분 이상 경과했습니다. |
| 404 | quote_not_found |
계정에 해당 견적이 없습니다. |
| 409 | quote_used |
해당 견적으로 이미 요청이 시작되었습니다. |
| 400 | max_price_exceeded |
모델의 단위당 비용이 provider.max_price보다 높습니다. |
| 400 | unsupported_routing_option |
max_price 이외의 provider 옵션입니다. |
| 404 | file_not_found |
계정에 해당 업로드 파일이 없거나, 만료되었습니다. |
| 413 | file_too_large |
10 MB를 초과하는 업로드입니다. |
| 429 | too_many_files |
이미 500개의 업로드 파일이 보관되어 있습니다. 일부를 삭제하거나 만료될 때까지 기다려 주세요. |
| 503 | files_unavailable |
현재 업로드를 이용할 수 없습니다. |
| 413 | request_too_large |
요청이 크기 제한(40 MB)을 초과했습니다. 사진은 https:// 링크로 보내고, 긴 녹음 파일은 분할하여 보내주세요. |
| 402 | insufficient_credits |
잔액이 작업의 최대 비용을 충당할 수 없습니다. 메시지에 필요한 금액이 표시됩니다. |
| 404 | model_not_found / not_found |
해당 모델이 없거나, 계정에 해당 작업이 없습니다. |
| 404 | artifact_expired |
파일이 더 이상 보관되지 않습니다 (위 참조). |
| 429 | rate_limited |
Retry-After에 표시된 시간(표시되지 않은 경우 몇 초)만큼 기다린 후 다시 시도해 주세요. X-RateLimit-Remaining는 이번 분에 남은 요청 수를 보여줍니다. |
| 503 | no_available_provider |
현재 이 작업을 수행할 수 있는 판매자가 없습니다. UberLLM이 이미 다른 판매자들을 시도했습니다. 메시지에 현재 작동하는 동일한 종류의 모델 이름이 표시됩니다. |