API 레퍼런스
오픈 프로바이더 네트워크 위에서 동작하는 OpenAI 호환 추론. 어떤 OpenAI SDK든 베이스 URL만 바꾸면 기존 코드를 그대로 쓰면서 사용한 만큼 크레딧으로 지불합니다.
소개
#핵심 엔드포인트는 OpenAI의 /v1/* 형식과 1:1로 대응합니다. OpenAI Python / Node SDK의 base_url만 바꾸면 나머지 애플리케이션은 그대로입니다. OpenAlchemy 확장(보이스, 오디오 워터마크, 이미지, 비디오, OCR, 의류 분할)은 따로 표시했습니다.
OpenAI와 다른 점은 세 가지입니다.
인증
#API는 Bearer 토큰으로 인증합니다. 키는 /api-keys에서 발급하세요. 키는 생성 시 한 번만 표시되며, 당사는 솔트 처리된 해시만 저장합니다. 비밀번호처럼 다루세요.
모든 요청에 Authorization 헤더가 필요합니다. 키는 사용할 수 있는 모델을 제한할 수 있으며, 범위 밖의 모델을 요청하면 403 model_not_allowed를 반환합니다.
유효한 키를 브라우저 번들, 모바일 앱, 공개 Git 저장소에 넣지 마세요. 키가 유출되면 즉시 /api-keys에서 폐기하세요.
Authorization: Bearer $OPENALCHEMY_API_KEY베이스 URL
#필요한 네트워크 엔드포인트는 이것 하나입니다.
https://api.openalchemy.ioAPI를 호출하려면 /v1/…를 붙입니다. 서버가 워커를 선택해 요청을 전달하고, 결과를 반환하며, 완료 시 과금합니다. 모두 하나의 응답 안에서 끝납니다.
# Python — works for chat, vision, embeddings, audio.
from openai import OpenAI
client = OpenAI(
base_url="https://api.openalchemy.io/v1",
api_key=os.environ["OPENALCHEMY_API_KEY"],
)응답 메타데이터
#모든 JSON 응답에는 x_openalchemy 블록이 포함됩니다. 표준 SDK는 알 수 없는 필드를 무시하므로 기존 코드에는 영향이 없지만, 디버깅할 때 가장 먼저 확인할 곳입니다.
request_id— 문의 시 알려 주세요.worker_id— 요청을 처리한 프로바이더.engine_latency_ms— 네트워크를 제외한 순수 GPU 처리 시간.usage.cost— 차감된 크레딧(고정소수점 문자열).
/logs 페이지에 같은 필드가 기록되어 있어 요청 전체를 검색할 수 있습니다.
{
"id": "cmpl-…",
"object": "chat.completion",
"model": "llama-3.1-70b-instruct",
"choices": [ … ],
"usage": { "prompt_tokens": 24, "completion_tokens": 19, "total_tokens": 43 },
"x_openalchemy": {
"request_id": "req_01HG…",
"tier": "m",
"worker_id": "wrk_4f…",
"engine_request_id": "vllm-…",
"engine_latency_ms": 412,
"upstream_latency_ms": 438,
"usage": {
"input_tokens": 24,
"output_tokens": 19,
"total_tokens": 43,
"cost": "0.000086"
}
}
}전체 엔드포인트
#공개된 모든 엔드포인트입니다. 각 경로를 베이스 URL 뒤에 붙여 호출합니다. 아래 엔드포인트 설명으로 이동하거나, 모델 카탈로그에서 엔드포인트별 제공 모델을 확인하세요.
/v1/chat/completions스트리밍POST/v1/chat/completions비전베타GET/v1/models목록POST/v1/embeddings벡터베타POST/v1/rerank리랭크베타POST/v1/audio/transcriptions음성 인식베타POST/v1/audio/speech음성 합성베타POST/v1/audio/speech/cancel취소베타GET/v1/audio/voices보이스베타POST/v1/audio/voices클론베타GET/v1/audio/voices/{voice_id}/clip참조 음성베타DELETE/v1/audio/voices/{voice_id}삭제베타POST/v1/audio/watermark/embed워터마크 삽입베타POST/v1/audio/watermark/detect워터마크 검출베타POST/v1/images/local/generations이미지 생성베타POST/v1/images/local/edits이미지 편집베타POST/v1/videos비디오 생성베타GET/v1/videos목록베타GET/v1/videos/availability가용성베타GET/v1/videos/{id}상태베타GET/v1/videos/{id}/content다운로드베타POST/v1/videos/{id}/cancel취소베타POST/v1/ocr문자 인식베타POST/v1/garment/segment의류 검출베타모델 목록 조회
#/v1/models네트워크가 현재 제공하는 모든 모델을 가용 용량, 티어, 기능 메타데이터와 함께 반환합니다. endpoint_type으로 필터링하고(chat / embedding / rerank / stt / tts / image / video 등), live_workers로 폴백 여부를 판단하세요.
curl https://api.openalchemy.io/v1/models \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY"{
"object": "list",
"data": [
{
"id": "llama-3.1-70b-instruct",
"object": "model",
"endpoint_type": "chat",
"tier": "m",
"family": "llama-3.1",
"context_window": 131072,
"params_b": 70,
"live_workers": 4,
"online": true
},
…
]
}채팅 완성
#/v1/chat/completions대화에 대한 모델 응답을 생성합니다. 가장 기본이 되는 OpenAI 호환 엔드포인트입니다.
OpenAI v1 호환 — 어떤 OpenAI SDK든 `base_url`과 키만 바꾸면 됩니다.
| 이름 | 타입 | 설명 |
|---|---|---|
model필수 | string | /v1/models에서 가져온 모델 ID. |
messages필수 | array<{role, content}> | 대화 턴. role은 system / user / assistant. |
temperature | number 0–2기본값 1 | 샘플링 온도. |
top_p | number 0–1기본값 1 | Nucleus 샘플링 누적 확률. |
max_tokens | integer기본값 2048 | 생성할 최대 토큰 수. |
presence_penalty | number -2…2기본값 0 | 이미 등장한 토큰에 페널티를 줍니다. |
frequency_penalty | number -2…2기본값 0 | 출현 빈도에 비례해 토큰에 페널티를 줍니다. |
stop | string | string[] | 생성을 멈추는 시퀀스. |
response_format | { type: 'text' | 'json_object' } | JSON 출력을 강제합니다. |
stream | boolean기본값 false | SSE로 스트리밍합니다. 마지막 청크에 usage가 포함됩니다. |
{
"id": "cmpl-…",
"object": "chat.completion",
"model": "<model>",
"choices": [{
"index": 0,
"message": { "role": "assistant", "content": "…" },
"finish_reason": "stop"
}],
"usage": { "prompt_tokens": N, "completion_tokens": N, "total_tokens": N },
"x_openalchemy": {
"request_id": "req_…",
"tier": "s",
"worker_id": "…",
"engine_latency_ms": …,
"usage": { "input_tokens": N, "output_tokens": N, "cost": "0.0008" }
}
}invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.model_not_found등록되지 않은 모델 ID입니다.rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.model_not_priced이 모델 티어의 요금이 아직 설정되지 않았습니다.engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.curl https://api.openalchemy.io/v1/chat/completions \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.1-70b-instruct",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Say hi in one sentence."
}
],
"temperature": 0.7,
"max_tokens": 256
}'비전
#/v1/chat/completions채팅 완성과 같은 엔드포인트에 이미지 파트를 포함해 보냅니다. 비전 지원 모델을 사용하세요.
OpenAI Vision 형식 — /v1/models에서 비전 지원 모델을 고르세요.
| 이름 | 타입 | 설명 |
|---|---|---|
model필수 | string | 비전 지원 모델 ID. |
messages필수 | array<{role, content: (string | ContentPart[])}> | 각 파트는 {type:'text', text} 또는 {type:'image_url', image_url:{url, detail}}. |
image_url.url | string | https://… URL 또는 data:image/...;base64,… (base64 기준 이미지당 약 6MB까지). |
image_url.detail | 'low' | 'auto' | 'high'기본값 'auto' | low: 이미지당 85토큰 고정. high: 85 + 170 × 타일 수 (768×768이면 약 765). |
temperature | number 0–2기본값 0.2 | 채팅과 동일. |
max_tokens | integer기본값 1024 | 채팅과 동일. |
// Same shape as /v1/chat/completions.
// x_openalchemy.usage.image_tokens is the per-request image token total.invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.model_not_found등록되지 않은 모델 ID입니다.rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.model_not_priced이 모델 티어의 요금이 아직 설정되지 않았습니다.curl https://api.openalchemy.io/v1/chat/completions \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen2.5-vl-72b",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "What'\''s in this image?"
},
{
"type": "image_url",
"image_url": {
"url": "https://images.example.com/cat.jpg",
"detail": "auto"
}
}
]
}
],
"max_tokens": 512
}'임베딩
#/v1/embeddings하나 또는 여러 문자열을 검색·클러스터링·RAG용 밀집 벡터로 변환합니다.
OpenAI Embeddings v1 호환.
| 이름 | 타입 | 설명 |
|---|---|---|
model필수 | string | 임베딩 모델 ID. |
input필수 | string | string[] | 임베딩할 문자열(하나 또는 배열). |
dimensions | integer | Matryoshka 학습 모델에서는 벡터를 이 차원 수로 자릅니다. 그 외에는 무시됩니다. |
encoding_format | 'float' | 'base64'기본값 'float' | 반환되는 벡터의 형식. |
{
"object": "list",
"data": [
{ "object": "embedding", "embedding": [0.0123, -0.045, …], "index": 0 },
…
],
"model": "<model>",
"usage": { "prompt_tokens": N, "total_tokens": N },
"x_openalchemy": { "usage": { "input_tokens": N, "cost": "…" } }
}invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.model_not_found등록되지 않은 모델 ID입니다.rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.model_not_priced이 모델 티어의 요금이 아직 설정되지 않았습니다.curl https://api.openalchemy.io/v1/embeddings \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nomic-embed-text-v1.5",
"input": [
"The quick brown fox",
"jumps over the lazy dog"
]
}'리랭크
#/v1/rerank쿼리에 대해 N개의 후보 문서를 재정렬합니다. Cohere 호환 요청 형식입니다.
Cohere /v2/rerank 호환 (`model`, `query`, `documents`, `top_n`).
| 이름 | 타입 | 설명 |
|---|---|---|
model필수 | string | 리랭커 모델 ID. |
query필수 | string | 검색 쿼리. |
documents필수 | string[] | { text: string }[] | 재정렬할 후보 문서. |
top_n | integer | 상위 N개만 반환합니다. 생략하면 전체. |
return_documents | boolean기본값 false | 응답에 각 문서의 텍스트를 포함합니다. |
{
"results": [
{ "index": 2, "relevance_score": 0.97 },
{ "index": 0, "relevance_score": 0.81 },
…
],
"x_openalchemy": {
"usage": {
"query_tokens": Q,
"document_tokens": Σ,
"total_tokens": Q + Σ,
"cost": "…"
}
}
}invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.model_not_found등록되지 않은 모델 ID입니다.rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.model_not_priced이 모델 티어의 요금이 아직 설정되지 않았습니다.curl https://api.openalchemy.io/v1/rerank \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bge-reranker-v2-m3",
"query": "What is OpenAlchemy?",
"documents": [
"OpenAlchemy is a distributed inference network where independent providers run open models for credits.",
"Cats are popular household pets.",
"Workers connect to the grid and serve OpenAI-compatible traffic."
],
"top_n": 2
}'음성 인식(전사)
#/v1/audio/transcriptions음성을 텍스트로. 오디오 파일을 multipart로 업로드하면 Whisper 호환 응답을 반환합니다.
OpenAI Whisper v1 호환. multipart/form-data.
| 이름 | 타입 | 설명 |
|---|---|---|
file필수 | binary | mp3 / wav / m4a / webm / flac. 요청당 25MB 이하. |
model필수 | string | STT 모델 ID. |
language | string | ISO-639-1 (예: 'en', 'ja'). 생략하면 자동 감지. |
prompt | string | 인식을 유도하는 선택 텍스트. 전문 용어에 유용합니다. |
response_format | 'json' | 'text' | 'srt' | 'vtt' | 'verbose_json'기본값 'json' | 출력 형식. |
temperature | number 0–1기본값 0 | 샘플링 온도(거의 필요 없음). |
// json:
{ "text": "…transcript…" }
// verbose_json (adds duration + segments):
{ "text": "…", "duration": 12.34, "language": "en", "segments": [ … ] }
// srt / vtt: plain text subtitle file in the matching format.invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.model_not_found등록되지 않은 모델 ID입니다.rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.model_not_priced이 모델 티어의 요금이 아직 설정되지 않았습니다.curl https://api.openalchemy.io/v1/audio/transcriptions \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-F file=@/path/to/audio.mp3 \
-F model=whisper-large-v3 \
-F response_format=json음성 합성
#/v1/audio/speech텍스트를 음성으로. 오디오 바이너리를 반환하며, 사용량 메타데이터는 응답 헤더에 들어갑니다.
OpenAI TTS v1 호환. 현재 출력은 WAV입니다.
| 이름 | 타입 | 설명 |
|---|---|---|
model필수 | string | TTS 모델 ID. |
input필수 | string | 합성할 텍스트. |
voice | string | 보이스 ID — 기본 보이스 또는 내 클론 보이스. GET /v1/audio/voices로 목록을 볼 수 있습니다. |
response_format | 'wav' | 'mp3' | 'opus'기본값 'wav' | 오디오 컨테이너. mp3/opus는 엔진 변환 지원 전까지 501을 반환합니다. |
speed | number 0.5–2.0기본값 1 | 재생 속도 배율. |
stream | boolean기본값 false | 생성되는 대로 청크 WAV를 전달합니다(저지연 재생). 중간에 끊어도 생성된 분량은 과금됩니다. |
// Body is binary audio (Content-Type: audio/wav).
// Inspect the response headers:
// X-Openalchemy-Request-Id
// X-Openalchemy-Audio-Seconds
// X-Openalchemy-Cost
// X-Engine-Request-Id (pass to /v1/audio/speech/cancel)invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.model_not_found등록되지 않은 모델 ID입니다.rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.model_not_priced이 모델 티어의 요금이 아직 설정되지 않았습니다.curl https://api.openalchemy.io/v1/audio/speech \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "cosyvoice2",
"input": "Hello from OpenAlchemy.",
"voice": "en_alice",
"response_format": "wav"
}' \
--output speech.wav음성 합성 취소
#/v1/audio/speech/cancel진행 중인 /v1/audio/speech 합성을 중지해 워커의 GPU를 해제합니다. 베스트 에포트로 항상 202를 반환합니다. 이미 전송된 오디오는 과금됩니다.
OpenAlchemy 확장 (OpenAI 엔드포인트가 아님).
| 이름 | 타입 | 설명 |
|---|---|---|
request_id필수 | string | /v1/audio/speech가 반환한 X-Engine-Request-Id (또는 해당 호출에서 지정한 X-Request-Id). |
// 202 Accepted (empty body)invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.curl -X POST https://api.openalchemy.io/v1/audio/speech/cancel \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"request_id": "<X-Engine-Request-Id>"}'보이스
#/v1/audio/voices기본 보이스와 내 클론 보이스 목록, 짧은 참조 음성으로 보이스 클론 생성(제로샷, 즉시 사용 가능), 클론의 참조 음성 조회, 클론 삭제를 할 수 있습니다.
OpenAlchemy 확장. 클론 보이스는 내 계정에서만 사용할 수 있습니다.
/v1/audio/voices기본 보이스와 클론 보이스 목록: {data: [{id, name, kind, language}]}./v1/audio/voices보이스를 클론합니다 (multipart 필드는 아래 표 참고)./v1/audio/voices/{voice_id}/clip클론 보이스의 참조 음성(audio_b64)과 전사문. 내 클론만 가능./v1/audio/voices/{voice_id}내 클론 보이스를 삭제합니다. 기본 보이스는 삭제할 수 없습니다.| 이름 | 타입 | 설명 |
|---|---|---|
file필수 | binary | 참조 음성 (WAV 또는 MP3, 최대 20MB). |
name필수 | string | 1~64자 (영문, 숫자, _, -). 이 값이 보이스 ID가 됩니다. |
language필수 | string | zh, en, ja, zh_en, ja_en, zh_ja 중 하나. |
reference_text필수 | string | 참조 음성의 정확한 전사문. |
// GET /v1/audio/voices
{ "data": [
{ "id": "en_alice", "name": "en_alice", "kind": "builtin", "language": "en" },
{ "id": "my_voice", "name": "my_voice", "kind": "cloned", "language": "ja" }
] }
// POST /v1/audio/voices
{ "id": "my_voice", "name": "my_voice", "kind": "cloned", "language": "ja", "status": "ready" }invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.invalid_namename이 1~64자의 영문·숫자·_·-가 아닙니다.invalid_languagelanguage가 지원되는 값이 아닙니다.not_found해당 ID의 클론 보이스가 계정에 없습니다.curl https://api.openalchemy.io/v1/audio/voices \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-F file=@reference.wav \
-F name=my_voice \
-F language=ja \
-F reference_text="こんにちは、今日はいい天気ですね。"오디오 워터마크
#/v1/audio/watermark/embed오디오에 들리지 않는 16비트 워터마크를 삽입하거나 검출합니다 (AudioSeal). 오디오 초 단위로 과금합니다.
OpenAlchemy 확장 (OpenAI 엔드포인트가 아님).
/v1/audio/watermark/embed워터마크가 삽입된 파일 자체를 보낸 것과 같은 형식(audio/mpeg 또는 audio/wav)으로 반환합니다. 요청 ID·message·비용은 응답 헤더에 들어갑니다./v1/audio/watermark/detect워터마크 유무, 신뢰도, 디코딩한 message를 반환합니다.| 이름 | 타입 | 설명 |
|---|---|---|
audio_b64필수 | string | WAV 또는 MP3 오디오의 base64 (최대 50MB). data: URL도 가능. |
message | integer 0–65535 | embed 전용(embed에서는 필수): 삽입할 16비트 값. 콘텐츠와의 매핑은 사용자가 관리합니다. |
// embed → audio bytes; headers:
// X-OpenAlchemy-Request-Id, X-OpenAlchemy-Cost,
// X-Watermark-Message, X-Audio-Seconds
// detect →
{ "watermarked": true, "confidence": 0.98, "message": 4242,
"x_openalchemy": { "request_id": "req_…", "worker_id": "…",
"usage": { "audio_seconds": 12, "cost": "…" } } }missing_audioaudio_b64가 없거나 비어 있습니다.bad_messageembed: message는 0~65535 정수여야 합니다.invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.audio_too_large오디오가 50MB를 초과합니다.curl https://api.openalchemy.io/v1/audio/watermark/embed \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"audio_b64\": \"$(base64 -w0 song.mp3)\", \"message\": 4242}" \
-o song.watermarked.mp3이미지 생성
#/v1/images/local/generationsGrid GPU에서 PNG 1장을 생성합니다. 생성이 끝나면 JSON을 반환합니다(스트리밍 없음).
OpenAI Images 형식의 요청/응답을 별도 경로로 제공합니다. SDK에서는 client.post('/images/local/generations', …)를 사용하세요 (images.generate()는 다른 경로를 호출합니다).
| 이름 | 타입 | 설명 |
|---|---|---|
model | string | /v1/models의 이미지 모델 (endpoint_type=image). |
prompt필수 | string | 이미지 설명 (1~32,000자). |
n | integer기본값 1 | 1만 가능 (요청당 1장). |
size | string기본값 1024x1024 | WIDTHxHEIGHT. 16의 배수, 각 변 최대 1536. |
response_format | string기본값 b64_json | b64_json만 지원. data[0].b64_json을 디코딩하면 PNG가 됩니다. |
seed | integer | 0~4294967295. 생략하면 무작위. |
steps | integer기본값 4 | 샘플링 스텝 수 (1~50). |
guidance_scale | number기본값 4 | 가이던스 스케일 (0~30). |
{
"created": 1713833628,
"data": [{ "b64_json": "<base64 PNG>" }],
"x_openalchemy": {
"request_id": "…", "worker_id": "…", "provider": "local",
"usage": { "images": 1, "cost": "…" }
}
}invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.model_not_found등록되지 않은 모델 ID입니다.validation_error지원하지 않거나 잘못된 파라미터 (quality, background, output_format, stream, mask 미지원).engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.curl https://api.openalchemy.io/v1/images/local/generations \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "a lighthouse at dusk, watercolor", "size": "1024x1024"}'이미지 편집
#/v1/images/local/edits참조 이미지 1장과 프롬프트로 PNG를 생성합니다. multipart/form-data로 보내며, 편집할 때마다 참조 이미지를 다시 업로드합니다.
OpenAI Images 편집 기능 중 참조 이미지 1장만 별도 경로로 제공합니다. mask와 여러 이미지는 지원하지 않습니다.
| 이름 | 타입 | 설명 |
|---|---|---|
image필수 | file | PNG / JPEG / WebP 1장, 최대 25MiB (필드명 image). |
model | string | /v1/models의 이미지 모델 (endpoint_type=image). |
prompt필수 | string | 이미지 설명 (1~32,000자). |
n | integer기본값 1 | 1만 가능 (요청당 1장). |
size | string기본값 1024x1024 | WIDTHxHEIGHT. 16의 배수, 각 변 최대 1536. |
response_format | string기본값 b64_json | b64_json만 지원. data[0].b64_json을 디코딩하면 PNG가 됩니다. |
seed | integer | 0~4294967295. 생략하면 무작위. |
steps | integer기본값 4 | 샘플링 스텝 수 (1~50). |
guidance_scale | number기본값 4 | 가이던스 스케일 (0~30). |
{
"created": 1713833628,
"data": [{ "b64_json": "<base64 PNG>" }],
"x_openalchemy": {
"request_id": "…", "worker_id": "…", "provider": "local",
"usage": { "images": 1, "cost": "…" }
}
}invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.model_not_found등록되지 않은 모델 ID입니다.validation_error지원하지 않거나 잘못된 파라미터 (quality, background, output_format, stream, mask 미지원).engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.empty_image참조 이미지가 비어 있습니다.image_too_large참조 이미지가 25MiB를 초과합니다.curl https://api.openalchemy.io/v1/images/local/edits \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-F image=@input.png \
-F prompt="same scene, at night"비디오 생성
#/v1/videosGrid GPU에서 비디오 샷 1개를 생성합니다. 모델: minimax-h3 (사운드 포함 4~15초, 768P; still: true면 PNG 키프레임 1장), wan2.2-s2v (키프레임 + 오디오로 노래·말하기 샷, 480P / 576P / 720P), wan2.2-i2v (키프레임이 프롬프트대로 움직임, 2~10초, 16fps, 480P / 576P / 720P), wan2.2-animate (키프레임 캐릭터가 드라이빙 영상의 동작을 수행, 480P), latentsync-1.6 (완성된 클립의 입을 새 음성에 다시 맞춤). minimax-h3도 audio_url을 받습니다 (mode ref에서는 목소리, t2v / i2v에서는 사운드트랙). 비동기 방식입니다. POST가 202와 id를 반환하면 status가 succeeded가 될 때까지 GET /v1/videos/{id}를 폴링한 뒤 output.url 또는 GET /v1/videos/{id}/content에서 받습니다.
Kie의 MiniMax H3 API와 같은 형태의 OpenAlchemy 확장. 모델·해상도별 단가로 출력 초 단위 과금 (still은 장당). 제출 시 예상 금액 전액을 홀드하고 실패 또는 취소 시 해제합니다. 베타.
/v1/videos샷 제출 → 202 {id, status: "queued"}. 온라인 워커가 없으면 즉시 503 no_video_worker를 반환하며 과금되지 않습니다./v1/videos이 프로젝트의 내 샷(최신순). 쿼리: limit (1~100, 기본 20), after (이전 페이지의 last_id), status./v1/videos/availability?model=지금 샷을 시작할 수 있는지: available, workers_online, workers_free, queue_depth. model은 minimax-h3 (mode ref는 minimax-h3-ref), wan2.2-s2v, wan2.2-i2v, wan2.2-animate 또는 latentsync-1.6./v1/videos/{id}status, stage, progress (샘플링 진행률 0~100), credits, 성공 후에는 짧게 유효한 output.url을 포함한 output./v1/videos/{id}/content짧게 유효한 서명된 mp4 URL로 302 리디렉션. 성공 전에는 409, 보존 기간(기본 7일)이 지나면 410./v1/videos/{id}/cancel대기 중이거나 실행 중인 샷을 취소합니다. 홀드된 크레딧은 전액 해제됩니다.| 이름 | 타입 | 설명 |
|---|---|---|
model | string기본값 "minimax-h3" | minimax-h3, wan2.2-s2v, wan2.2-i2v, wan2.2-animate 또는 latentsync-1.6. |
mode | string기본값 "t2v" | minimax-h3: t2v (프롬프트만), i2v (첫/마지막 프레임), ref (참조 이미지 1~9장, 프롬프트에서 <Picture 1>, <Picture 2>…로 지정). wan2.2-s2v: s2v. wan2.2-i2v: i2v. wan2.2-animate: animate. latentsync-1.6: lipsync. |
prompt필수 | string | 샷의 내용(사운드 포함). 최대 8,000자. latentsync-1.6에서는 사용하지 않습니다. |
duration | integer 4–15기본값 5 | minimax-h3: 길이(초, 24fps), still은 생략. wan2.2-s2v: 생략 (길이는 오디오, 2~45초). wan2.2-i2v: 2~10초 (기본 5, 16fps). wan2.2-animate: 선택, 드라이빙 영상 앞부분 N초 (기본 전체, 2~30초). latentsync-1.6: 생략 (길이는 오디오). |
resolution | string기본값 "768P" | minimax-h3: 768P만 (2K는 422). wan2.2-s2v: 480P (기본), 576P, 720P (해상도별 초당 단가). wan2.2-i2v: 480P (기본), 576P, 720P. wan2.2-animate: 480P. latentsync-1.6: 생략 (입력 영상 크기 유지). |
aspect_ratio | string기본값 "16:9" | t2v와 ref에서 사용. i2v는 프레임 비율을 따릅니다. |
seed | integer | 고정하면 같은 출력을 재현할 수 있습니다. 생략하면 무작위. |
first_frame_url | string | i2v (minimax-h3, wan2.2-i2v), s2v, animate: 시작 프레임(PNG/JPEG)의 https URL, base64 또는 data: URL. |
last_frame_url | string | i2v: 마지막 프레임. |
reference_image_urls | string[] (1–9) | ref: 참조 이미지 (https, base64 또는 data: URL). |
still | boolean기본값 false | minimax-h3 t2v / ref: 비디오 대신 PNG 키프레임 1장 생성 (장당 과금). control_image_url (포즈·깊이·선화 템플릿)과 control_strength 0~2 선택 가능. |
audio_url | string | wan2.2-s2v: 구동 오디오 (wav / mp3 / aac, https 또는 data: URL, 50MB 이하, 2~45초). first_frame_url이 키프레임. 오디오는 16fps 출력에 합쳐집니다. latentsync-1.6: 새 음성 트랙 (wav / mp3 / aac / m4a, 20MB 이하, 0.5초 이상, 영상보다 0.5초 넘게 길지 않게). minimax-h3 (30초 이하, still 불가): mode ref에서는 프롬프트의 <Audio 1> 목소리, t2v / i2v에서는 첫 프레임부터 맞추는 사운드트랙 가이드 (최종 오디오는 H3가 생성). 클립 길이는 duration 그대로. |
driving_video_url | string | wan2.2-animate: 수행할 동작 (mp4 / mov / webm, https 또는 data: URL, 50MB 이하), 출력과 같은 화면비 필요 (다르면 422 driving_aspect_mismatch). first_frame_url이 캐릭터. 출력에 오디오 없음. |
video_url | string | latentsync-1.6: 다시 맞출 클립 (mp4 / mov / webm, https 또는 data: URL, 50MB 이하, 30초 이하). 화면은 그대로이고 입 부분만 바뀝니다. 출력은 25fps, audio_url 오디오가 합쳐짐. |
steps | integer 1–50 | 모델 기본값 대신 사용할 샘플링 스텝 수 (minimax-h3 8, mode ref 4, wan2.2-s2v 4 — turbo false면 20, wan2.2-i2v 6, wan2.2-animate 4). 생성 시간과 품질이 바뀌며 가격은 같습니다. |
turbo | boolean기본값 true | wan2.2-s2v 전용: false면 4스텝 증류 LoRA 없이 생성 (풀 샘플러, 20스텝, CFG 6 — 몇 배 느리지만 베이스 모델에 가까움). 다른 모델에서 false는 400 turbo_not_supported. |
// POST /v1/videos → 202
{ "id": "video_…", "object": "video", "status": "queued", "model": "minimax-h3",
"mode": "t2v", "duration": 5, "resolution": "768P", "estimated_credits": "…" }
// GET /v1/videos/{id}
{ "id": "video_…", "object": "video",
"status": "running", // queued | running | uploading | succeeded | failed | cancelled
"stage": "rendering", // queued | evicting | uploading_frames | rendering | decoding | storing; null once finished
"progress": 37, // sampling percent 0–100 (0 until sampling starts, 100 when succeeded)
"credits": null, // settled credits once succeeded
"output": null, // when succeeded:
// { "mime_type": "video/mp4", "duration": 5, "width": 1344, "height": 768, "fps": 24,
// "has_audio": true, "bytes": 2400000, "seed": 7, "expires_at": 1760600000,
// "url": "https://…signed…", "url_expires_in": 900 }
"error": null } // { "code", "message" } when failed / cancelled
// GET /v1/videos?limit=20&after=video_…&status=succeeded
{ "object": "list", "data": [ /* same shape as GET /v1/videos/{id} */ ],
"has_more": true, "first_id": "video_…", "last_id": "video_…" }
// GET /v1/videos/availability?model=minimax-h3
{ "object": "video.availability", "model": "minimax-h3",
"available": true, "workers_online": 2, "workers_free": 1, "queue_depth": 0 }invalid_durationduration이 4~15초 범위를 벗어났습니다.invalid_modemode가 t2v / i2v / ref 중 하나가 아닙니다.missing_promptprompt가 비어 있습니다.invalid_stepssteps가 1~50 범위를 벗어났습니다.turbo_not_supportedwan2.2-s2v 이외의 모델에 turbo: false를 보냈습니다.invalid_resolution모델이 지원하지 않는 resolution입니다 (resolution 참조).driving_aspect_mismatchwan2.2-animate: 드라이빙 영상의 화면비가 aspect_ratio와 다릅니다.audio_needs_s2vstill: true와 함께, 또는 오디오를 받지 않는 모델에 audio_url을 보냈습니다.audio_longer_than_videolatentsync-1.6: 오디오가 영상보다 0.5초 넘게 깁니다.invalid_after목록: after가 내 비디오의 ID가 아닙니다.invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용에 비해 크레딧이 부족합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.not_found이 계정에서 비디오 생성이 아직 활성화되지 않았거나 ID가 없습니다.video_not_ready샷이 성공하기 전에 콘텐츠를 요청했습니다.video_expired출력의 보존 기간이 지났습니다.resolution_not_supported2K가 요청되었습니다. 768P만 지원합니다.reference_video_not_supportedreference_video_urls는 아직 지원하지 않습니다.no_video_worker현재 이 모델/모드를 처리할 GPU 워커가 온라인이 아닙니다. 즉시 반환되며 과금되지 않습니다.# 1. Submit
curl https://api.openalchemy.io/v1/videos \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "minimax-h3", "mode": "t2v", "prompt": "waves on a pebble beach, gulls calling", "duration": 5}'
# 2. Poll until "status": "succeeded"
curl https://api.openalchemy.io/v1/videos/video_… \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY"
# 3. Download
curl -L https://api.openalchemy.io/v1/videos/video_…/content \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" -o shot.mp4OCR (문자 인식)
#/v1/ocr이미지 또는 PDF에서 텍스트를 추출합니다. PDF는 페이지별로 이미지화해 인식합니다(최대 50페이지). 페이지 단위로 과금합니다.
OpenAlchemy 확장 (OpenAI 엔드포인트가 아님). 이미지에 대해 질문하려면 비전 모델로 /v1/chat/completions를 사용하세요.
| 이름 | 타입 | 설명 |
|---|---|---|
model | string기본값 "paddleocr" | paddleocr (빠름, 줄별 박스 포함) 또는 /v1/models의 비전 모델 ID. |
image_b64필수 | string | 이미지(PNG/JPG/WebP) 또는 PDF의 base64. data: URL도 가능. 별칭: image. |
lang | string | PaddleOCR 언어 코드 (ch, en, japan, korean 등). 비전 모델에서는 무시됩니다. |
{
"text": "…full recognised text…",
// PaddleOCR — per-line text, confidence and box:
"lines": [ { "text": "…", "score": 0.99, "box": [[x0,y0],[x1,y1],[x2,y2],[x3,y3]] } ],
"page_count": 1,
// PDFs — one entry per page:
"pages": [ { "page_num": 1, "text": "…" } ],
"x_openalchemy": { "request_id": "req_…", "worker_id": "…", "usage": { "pages": 1, "cost": "…" } }
}missing_imageimage_b64(또는 image)가 없거나 비어 있습니다.bad_base64페이로드가 올바른 base64가 아닙니다.bad_pdfPDF를 열 수 없습니다.invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.too_many_pagesPDF가 50페이지를 초과합니다.engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.curl https://api.openalchemy.io/v1/ocr \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"model\": \"paddleocr\", \"lang\": \"japan\", \"image_b64\": \"$(base64 -w0 receipt.png)\"}"의류 분할
#/v1/garment/segment사진 속 의류와 각 위치를 찾습니다 (SegFormer 의류 파싱). 의류마다 마스크 중심점 1개를 반환합니다. 이미지 단위로 과금합니다.
OpenAlchemy 확장 (OpenAI 엔드포인트가 아님).
| 이름 | 타입 | 설명 |
|---|---|---|
model | string기본값 "segformer-b2-clothes" | segformer-b2-clothes (빠름) 또는 segformer-b3-clothes. |
image_b64필수 | string | PNG/JPG/WebP 사진의 base64 (최대 25MB). data: URL도 가능. 별칭: image. |
min_area_ratio | number 0–1 | 마스크 면적이 이미지에서 차지하는 비율이 이 값보다 작은 의류는 반환하지 않습니다. |
{
"model": "segformer-b2-clothes",
"width": 1000, "height": 1500,
// label: Dress | Upper-clothes | Skirt | Pants | Bag | Shoes | Hat | Scarf | Belt
"garments": [
{ "label": "Upper-clothes", "x": 473.2, "y": 739.5, "x_norm": 0.4732, "y_norm": 0.493,
"area_ratio": 0.0417, "bbox": [376.3, 534.7, 578.3, 931.6] }
],
"x_openalchemy": { "request_id": "req_…", "worker_id": "…", "usage": { "images": 1, "cost": "…" } }
}missing_imageimage_b64(또는 image)가 없거나 비어 있습니다.bad_base64페이로드가 올바른 base64가 아닙니다.invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.image_too_large이미지가 25MB를 초과합니다.engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.curl https://api.openalchemy.io/v1/garment/segment \
-H "Authorization: Bearer $OPENALCHEMY_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"image_b64\": \"$(base64 -w0 outfit.jpg)\"}"오류
#오류는 OpenAI와 같은 형식으로, message, type, code를 가진 error 객체의 JSON을 반환합니다. 같은 HTTP 상태에 여러 코드가 있을 수 있으므로 HTTP 상태가 아닌 code로 분기하세요.
invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.model_not_found등록되지 않은 모델 ID입니다.rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.model_not_priced이 모델 티어의 요금이 아직 설정되지 않았습니다.engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.{
"error": {
"message": "Insufficient credit balance for this request.",
"type": "billing_error",
"code": "insufficient_balance"
}
}요청 한도
#요청 한도는 API 키별로 두 가지 기준으로 설정됩니다. RPM(분당 요청 수)과 TPM(분당 토큰 수, 입력과 출력 합계)입니다. 둘 다 기본적으로 무료 등급 한도가 적용되며, 크레딧을 충전하면 상향됩니다.
한도를 넘으면 Retry-After 헤더(초)와 함께 429 rate_limited를 반환합니다. OpenAI SDK는 이를 자동으로 따릅니다. 직접 만든 클라이언트라면 잠시 기다린 뒤 다시 시도하세요.
특정 모델에서 503 no_workers_for_model이 계속되면 요청 한도가 아니라 처리 용량 부족 신호입니다. /models에서 비슷한 모델을 고르거나, 프로바이더를 추가할 수 있도록 알려 주세요.
x_openalchemy.request_id를 여쭤봅니다.