OpenAlchemyOpenAlchemy
문서

API 레퍼런스

오픈 프로바이더 네트워크 위에서 동작하는 OpenAI 호환 추론. 어떤 OpenAI SDK든 베이스 URL만 바꾸면 기존 코드를 그대로 쓰면서 사용한 만큼 크레딧으로 지불합니다.

소개

#

핵심 엔드포인트는 OpenAI의 /v1/* 형식과 1:1로 대응합니다. OpenAI Python / Node SDK의 base_url만 바꾸면 나머지 애플리케이션은 그대로입니다. OpenAlchemy 확장(보이스, 오디오 워터마크, 이미지, 비디오, OCR, 의류 분할)은 따로 표시했습니다.

OpenAI와 다른 점은 세 가지입니다.

  • 크레딧으로 지불합니다(1크레딧 = 0.001달러). 충전은 /billing에서 하며, 기능별 요금은 요금 페이지에 있습니다.
  • 모든 JSON 응답에는 요청 ID, 워커 ID, 엔진 지연 시간, 사용량 내역이 담긴 x_openalchemy 블록이 포함됩니다. 디버깅과 비용 파악에 유용합니다.
  • 추론은 실제 GPU를 운영하는 독립 프로바이더가 처리합니다. /models의 모델 카탈로그에서 모델별 실시간 가용 용량을 확인할 수 있습니다.

인증

#

API는 Bearer 토큰으로 인증합니다. 키는 /api-keys에서 발급하세요. 키는 생성 시 한 번만 표시되며, 당사는 솔트 처리된 해시만 저장합니다. 비밀번호처럼 다루세요.

모든 요청에 Authorization 헤더가 필요합니다. 키는 사용할 수 있는 모델을 제한할 수 있으며, 범위 밖의 모델을 요청하면 403 model_not_allowed를 반환합니다.

유효한 키를 브라우저 번들, 모바일 앱, 공개 Git 저장소에 넣지 마세요. 키가 유출되면 즉시 /api-keys에서 폐기하세요.

헤더
Authorization: Bearer $OPENALCHEMY_API_KEY

베이스 URL

#

필요한 네트워크 엔드포인트는 이것 하나입니다.

HTTPShttps://api.openalchemy.io

API를 호출하려면 /v1/…를 붙입니다. 서버가 워커를 선택해 요청을 전달하고, 결과를 반환하며, 완료 시 과금합니다. 모두 하나의 응답 안에서 끝납니다.

Python SDK
# 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 뒤에 붙여 호출합니다. 아래 엔드포인트 설명으로 이동하거나, 모델 카탈로그에서 엔드포인트별 제공 모델을 확인하세요.

모델 목록 조회

#
GET/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
    },
    …
  ]
}

채팅 완성

#
POST/v1/chat/completions

대화에 대한 모델 응답을 생성합니다. 가장 기본이 되는 OpenAI 호환 엔드포인트입니다.

OpenAI v1 호환 — 어떤 OpenAI SDK든 `base_url`과 키만 바꾸면 됩니다.

요청 본문
이름타입설명
model필수string/v1/models에서 가져온 모델 ID.
messages필수array<{role, content}>대화 턴. role은 system / user / assistant.
temperaturenumber 0–2
기본값 1
샘플링 온도.
top_pnumber 0–1
기본값 1
Nucleus 샘플링 누적 확률.
max_tokensinteger
기본값 2048
생성할 최대 토큰 수.
presence_penaltynumber -2…2
기본값 0
이미 등장한 토큰에 페널티를 줍니다.
frequency_penaltynumber -2…2
기본값 0
출현 빈도에 비례해 토큰에 페널티를 줍니다.
stopstring | string[]생성을 멈추는 시퀀스.
response_format{ type: 'text' | 'json_object' }JSON 출력을 강제합니다.
streamboolean
기본값 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" }
  }
}
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404model_not_found등록되지 않은 모델 ID입니다.
429rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.
503no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.
503model_not_priced이 모델 티어의 요금이 아직 설정되지 않았습니다.
502engine_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
}'
플레이그라운드에서 사용해 보기→
요청을 바로 조정하고 생성된 코드를 복사할 수 있습니다.

비전

#
POST/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.urlstringhttps://… URL 또는 data:image/...;base64,… (base64 기준 이미지당 약 6MB까지).
image_url.detail'low' | 'auto' | 'high'
기본값 'auto'
low: 이미지당 85토큰 고정. high: 85 + 170 × 타일 수 (768×768이면 약 765).
temperaturenumber 0–2
기본값 0.2
채팅과 동일.
max_tokensinteger
기본값 1024
채팅과 동일.
응답
// Same shape as /v1/chat/completions.
// x_openalchemy.usage.image_tokens is the per-request image token total.
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404model_not_found등록되지 않은 모델 ID입니다.
429rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.
503no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.
503model_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
}'
플레이그라운드에서 사용해 보기→
요청을 바로 조정하고 생성된 코드를 복사할 수 있습니다.

임베딩

#
POST/v1/embeddings

하나 또는 여러 문자열을 검색·클러스터링·RAG용 밀집 벡터로 변환합니다.

OpenAI Embeddings v1 호환.

요청 본문
이름타입설명
model필수string임베딩 모델 ID.
input필수string | string[]임베딩할 문자열(하나 또는 배열).
dimensionsintegerMatryoshka 학습 모델에서는 벡터를 이 차원 수로 자릅니다. 그 외에는 무시됩니다.
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": "…" } }
}
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404model_not_found등록되지 않은 모델 ID입니다.
429rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.
503no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.
503model_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"
  ]
}'
플레이그라운드에서 사용해 보기→
요청을 바로 조정하고 생성된 코드를 복사할 수 있습니다.

리랭크

#
POST/v1/rerank

쿼리에 대해 N개의 후보 문서를 재정렬합니다. Cohere 호환 요청 형식입니다.

Cohere /v2/rerank 호환 (`model`, `query`, `documents`, `top_n`).

요청 본문
이름타입설명
model필수string리랭커 모델 ID.
query필수string검색 쿼리.
documents필수string[] | { text: string }[]재정렬할 후보 문서.
top_ninteger상위 N개만 반환합니다. 생략하면 전체.
return_documentsboolean
기본값 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": "…"
    }
  }
}
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404model_not_found등록되지 않은 모델 ID입니다.
429rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.
503no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.
503model_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
}'
플레이그라운드에서 사용해 보기→
요청을 바로 조정하고 생성된 코드를 복사할 수 있습니다.

음성 인식(전사)

#
POST/v1/audio/transcriptions

음성을 텍스트로. 오디오 파일을 multipart로 업로드하면 Whisper 호환 응답을 반환합니다.

OpenAI Whisper v1 호환. multipart/form-data.

폼 필드 (multipart/form-data)
이름타입설명
file필수binarymp3 / wav / m4a / webm / flac. 요청당 25MB 이하.
model필수stringSTT 모델 ID.
languagestringISO-639-1 (예: 'en', 'ja'). 생략하면 자동 감지.
promptstring인식을 유도하는 선택 텍스트. 전문 용어에 유용합니다.
response_format'json' | 'text' | 'srt' | 'vtt' | 'verbose_json'
기본값 'json'
출력 형식.
temperaturenumber 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.
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404model_not_found등록되지 않은 모델 ID입니다.
429rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.
503no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.
503model_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
플레이그라운드에서 사용해 보기→
요청을 바로 조정하고 생성된 코드를 복사할 수 있습니다.

음성 합성

#
POST/v1/audio/speech

텍스트를 음성으로. 오디오 바이너리를 반환하며, 사용량 메타데이터는 응답 헤더에 들어갑니다.

OpenAI TTS v1 호환. 현재 출력은 WAV입니다.

요청 본문
이름타입설명
model필수stringTTS 모델 ID.
input필수string합성할 텍스트.
voicestring보이스 ID — 기본 보이스 또는 내 클론 보이스. GET /v1/audio/voices로 목록을 볼 수 있습니다.
response_format'wav' | 'mp3' | 'opus'
기본값 'wav'
오디오 컨테이너. mp3/opus는 엔진 변환 지원 전까지 501을 반환합니다.
speednumber 0.5–2.0
기본값 1
재생 속도 배율.
streamboolean
기본값 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)
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404model_not_found등록되지 않은 모델 ID입니다.
429rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.
503no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.
503model_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
플레이그라운드에서 사용해 보기→
요청을 바로 조정하고 생성된 코드를 복사할 수 있습니다.

음성 합성 취소

#
POST/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)
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
cURL
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>"}'

보이스

#
POST/v1/audio/voices

기본 보이스와 내 클론 보이스 목록, 짧은 참조 음성으로 보이스 클론 생성(제로샷, 즉시 사용 가능), 클론의 참조 음성 조회, 클론 삭제를 할 수 있습니다.

OpenAlchemy 확장. 클론 보이스는 내 계정에서만 사용할 수 있습니다.

엔드포인트
GET/v1/audio/voices기본 보이스와 클론 보이스 목록: {data: [{id, name, kind, language}]}.
POST/v1/audio/voices보이스를 클론합니다 (multipart 필드는 아래 표 참고).
GET/v1/audio/voices/{voice_id}/clip클론 보이스의 참조 음성(audio_b64)과 전사문. 내 클론만 가능.
DELETE/v1/audio/voices/{voice_id}내 클론 보이스를 삭제합니다. 기본 보이스는 삭제할 수 없습니다.
폼 필드 (multipart/form-data)
이름타입설명
file필수binary참조 음성 (WAV 또는 MP3, 최대 20MB).
name필수string1~64자 (영문, 숫자, _, -). 이 값이 보이스 ID가 됩니다.
language필수stringzh, 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" }
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
400invalid_namename이 1~64자의 영문·숫자·_·-가 아닙니다.
400invalid_languagelanguage가 지원되는 값이 아닙니다.
404not_found해당 ID의 클론 보이스가 계정에 없습니다.
cURL
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="こんにちは、今日はいい天気ですね。"

오디오 워터마크

#
POST/v1/audio/watermark/embed

오디오에 들리지 않는 16비트 워터마크를 삽입하거나 검출합니다 (AudioSeal). 오디오 초 단위로 과금합니다.

OpenAlchemy 확장 (OpenAI 엔드포인트가 아님).

엔드포인트
POST/v1/audio/watermark/embed워터마크가 삽입된 파일 자체를 보낸 것과 같은 형식(audio/mpeg 또는 audio/wav)으로 반환합니다. 요청 ID·message·비용은 응답 헤더에 들어갑니다.
POST/v1/audio/watermark/detect워터마크 유무, 신뢰도, 디코딩한 message를 반환합니다.
요청 본문
이름타입설명
audio_b64필수stringWAV 또는 MP3 오디오의 base64 (최대 50MB). data: URL도 가능.
messageinteger 0–65535embed 전용(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": "…" } } }
오류
400missing_audioaudio_b64가 없거나 비어 있습니다.
400bad_messageembed: message는 0~65535 정수여야 합니다.
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
413audio_too_large오디오가 50MB를 초과합니다.
cURL
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

이미지 생성

#
POST/v1/images/local/generations

Grid GPU에서 PNG 1장을 생성합니다. 생성이 끝나면 JSON을 반환합니다(스트리밍 없음).

OpenAI Images 형식의 요청/응답을 별도 경로로 제공합니다. SDK에서는 client.post('/images/local/generations', …)를 사용하세요 (images.generate()는 다른 경로를 호출합니다).

요청 본문
이름타입설명
modelstring/v1/models의 이미지 모델 (endpoint_type=image).
prompt필수string이미지 설명 (1~32,000자).
ninteger
기본값 1
1만 가능 (요청당 1장).
sizestring
기본값 1024x1024
WIDTHxHEIGHT. 16의 배수, 각 변 최대 1536.
response_formatstring
기본값 b64_json
b64_json만 지원. data[0].b64_json을 디코딩하면 PNG가 됩니다.
seedinteger0~4294967295. 생략하면 무작위.
stepsinteger
기본값 4
샘플링 스텝 수 (1~50).
guidance_scalenumber
기본값 4
가이던스 스케일 (0~30).
응답
{
  "created": 1713833628,
  "data": [{ "b64_json": "<base64 PNG>" }],
  "x_openalchemy": {
    "request_id": "…", "worker_id": "…", "provider": "local",
    "usage": { "images": 1, "cost": "…" }
  }
}
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404model_not_found등록되지 않은 모델 ID입니다.
422validation_error지원하지 않거나 잘못된 파라미터 (quality, background, output_format, stream, mask 미지원).
502engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.
cURL
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"}'

이미지 편집

#
POST/v1/images/local/edits

참조 이미지 1장과 프롬프트로 PNG를 생성합니다. multipart/form-data로 보내며, 편집할 때마다 참조 이미지를 다시 업로드합니다.

OpenAI Images 편집 기능 중 참조 이미지 1장만 별도 경로로 제공합니다. mask와 여러 이미지는 지원하지 않습니다.

폼 필드 (multipart/form-data)
이름타입설명
image필수filePNG / JPEG / WebP 1장, 최대 25MiB (필드명 image).
modelstring/v1/models의 이미지 모델 (endpoint_type=image).
prompt필수string이미지 설명 (1~32,000자).
ninteger
기본값 1
1만 가능 (요청당 1장).
sizestring
기본값 1024x1024
WIDTHxHEIGHT. 16의 배수, 각 변 최대 1536.
response_formatstring
기본값 b64_json
b64_json만 지원. data[0].b64_json을 디코딩하면 PNG가 됩니다.
seedinteger0~4294967295. 생략하면 무작위.
stepsinteger
기본값 4
샘플링 스텝 수 (1~50).
guidance_scalenumber
기본값 4
가이던스 스케일 (0~30).
응답
{
  "created": 1713833628,
  "data": [{ "b64_json": "<base64 PNG>" }],
  "x_openalchemy": {
    "request_id": "…", "worker_id": "…", "provider": "local",
    "usage": { "images": 1, "cost": "…" }
  }
}
오류
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404model_not_found등록되지 않은 모델 ID입니다.
422validation_error지원하지 않거나 잘못된 파라미터 (quality, background, output_format, stream, mask 미지원).
502engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.
400empty_image참조 이미지가 비어 있습니다.
413image_too_large참조 이미지가 25MiB를 초과합니다.
cURL
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"

비디오 생성

#
POST/v1/videos

Grid 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은 장당). 제출 시 예상 금액 전액을 홀드하고 실패 또는 취소 시 해제합니다. 베타.

엔드포인트
POST/v1/videos샷 제출 → 202 {id, status: "queued"}. 온라인 워커가 없으면 즉시 503 no_video_worker를 반환하며 과금되지 않습니다.
GET/v1/videos이 프로젝트의 내 샷(최신순). 쿼리: limit (1~100, 기본 20), after (이전 페이지의 last_id), status.
GET/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.
GET/v1/videos/{id}status, stage, progress (샘플링 진행률 0~100), credits, 성공 후에는 짧게 유효한 output.url을 포함한 output.
GET/v1/videos/{id}/content짧게 유효한 서명된 mp4 URL로 302 리디렉션. 성공 전에는 409, 보존 기간(기본 7일)이 지나면 410.
POST/v1/videos/{id}/cancel대기 중이거나 실행 중인 샷을 취소합니다. 홀드된 크레딧은 전액 해제됩니다.
요청 본문
이름타입설명
modelstring
기본값 "minimax-h3"
minimax-h3, wan2.2-s2v, wan2.2-i2v, wan2.2-animate 또는 latentsync-1.6.
modestring
기본값 "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에서는 사용하지 않습니다.
durationinteger 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: 생략 (길이는 오디오).
resolutionstring
기본값 "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_ratiostring
기본값 "16:9"
t2v와 ref에서 사용. i2v는 프레임 비율을 따릅니다.
seedinteger고정하면 같은 출력을 재현할 수 있습니다. 생략하면 무작위.
first_frame_urlstringi2v (minimax-h3, wan2.2-i2v), s2v, animate: 시작 프레임(PNG/JPEG)의 https URL, base64 또는 data: URL.
last_frame_urlstringi2v: 마지막 프레임.
reference_image_urlsstring[] (1–9)ref: 참조 이미지 (https, base64 또는 data: URL).
stillboolean
기본값 false
minimax-h3 t2v / ref: 비디오 대신 PNG 키프레임 1장 생성 (장당 과금). control_image_url (포즈·깊이·선화 템플릿)과 control_strength 0~2 선택 가능.
audio_urlstringwan2.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_urlstringwan2.2-animate: 수행할 동작 (mp4 / mov / webm, https 또는 data: URL, 50MB 이하), 출력과 같은 화면비 필요 (다르면 422 driving_aspect_mismatch). first_frame_url이 캐릭터. 출력에 오디오 없음.
video_urlstringlatentsync-1.6: 다시 맞출 클립 (mp4 / mov / webm, https 또는 data: URL, 50MB 이하, 30초 이하). 화면은 그대로이고 입 부분만 바뀝니다. 출력은 25fps, audio_url 오디오가 합쳐짐.
stepsinteger 1–50모델 기본값 대신 사용할 샘플링 스텝 수 (minimax-h3 8, mode ref 4, wan2.2-s2v 4 — turbo false면 20, wan2.2-i2v 6, wan2.2-animate 4). 생성 시간과 품질이 바뀌며 가격은 같습니다.
turboboolean
기본값 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 }
오류
400invalid_durationduration이 4~15초 범위를 벗어났습니다.
400invalid_modemode가 t2v / i2v / ref 중 하나가 아닙니다.
400missing_promptprompt가 비어 있습니다.
400invalid_stepssteps가 1~50 범위를 벗어났습니다.
400turbo_not_supportedwan2.2-s2v 이외의 모델에 turbo: false를 보냈습니다.
400invalid_resolution모델이 지원하지 않는 resolution입니다 (resolution 참조).
422driving_aspect_mismatchwan2.2-animate: 드라이빙 영상의 화면비가 aspect_ratio와 다릅니다.
400audio_needs_s2vstill: true와 함께, 또는 오디오를 받지 않는 모델에 audio_url을 보냈습니다.
400audio_longer_than_videolatentsync-1.6: 오디오가 영상보다 0.5초 넘게 깁니다.
400invalid_after목록: after가 내 비디오의 ID가 아닙니다.
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용에 비해 크레딧이 부족합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404not_found이 계정에서 비디오 생성이 아직 활성화되지 않았거나 ID가 없습니다.
409video_not_ready샷이 성공하기 전에 콘텐츠를 요청했습니다.
410video_expired출력의 보존 기간이 지났습니다.
422resolution_not_supported2K가 요청되었습니다. 768P만 지원합니다.
422reference_video_not_supportedreference_video_urls는 아직 지원하지 않습니다.
503no_video_worker현재 이 모델/모드를 처리할 GPU 워커가 온라인이 아닙니다. 즉시 반환되며 과금되지 않습니다.
cURL
# 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.mp4

OCR (문자 인식)

#
POST/v1/ocr

이미지 또는 PDF에서 텍스트를 추출합니다. PDF는 페이지별로 이미지화해 인식합니다(최대 50페이지). 페이지 단위로 과금합니다.

OpenAlchemy 확장 (OpenAI 엔드포인트가 아님). 이미지에 대해 질문하려면 비전 모델로 /v1/chat/completions를 사용하세요.

요청 본문
이름타입설명
modelstring
기본값 "paddleocr"
paddleocr (빠름, 줄별 박스 포함) 또는 /v1/models의 비전 모델 ID.
image_b64필수string이미지(PNG/JPG/WebP) 또는 PDF의 base64. data: URL도 가능. 별칭: image.
langstringPaddleOCR 언어 코드 (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": "…" } }
}
오류
400missing_imageimage_b64(또는 image)가 없거나 비어 있습니다.
400bad_base64페이로드가 올바른 base64가 아닙니다.
400bad_pdfPDF를 열 수 없습니다.
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
413too_many_pagesPDF가 50페이지를 초과합니다.
502engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.
cURL
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)\"}"

의류 분할

#
POST/v1/garment/segment

사진 속 의류와 각 위치를 찾습니다 (SegFormer 의류 파싱). 의류마다 마스크 중심점 1개를 반환합니다. 이미지 단위로 과금합니다.

OpenAlchemy 확장 (OpenAI 엔드포인트가 아님).

요청 본문
이름타입설명
modelstring
기본값 "segformer-b2-clothes"
segformer-b2-clothes (빠름) 또는 segformer-b3-clothes.
image_b64필수stringPNG/JPG/WebP 사진의 base64 (최대 25MB). data: URL도 가능. 별칭: image.
min_area_rationumber 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": "…" } }
}
오류
400missing_imageimage_b64(또는 image)가 없거나 비어 있습니다.
400bad_base64페이로드가 올바른 base64가 아닙니다.
401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
413image_too_large이미지가 25MB를 초과합니다.
502engine_unreachable추론 엔진에 연결할 수 없거나 시간이 초과되었습니다.
cURL
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로 분기하세요.

401invalid_api_keyBearer 토큰이 없거나 형식이 잘못되었거나 폐기되었습니다.
402insufficient_balance예상 비용이 사용 가능한 잔액을 초과합니다.
403model_not_allowed이 API 키는 요청한 모델에 대한 권한이 없습니다.
404model_not_found등록되지 않은 모델 ID입니다.
429rate_limited키별 RPM 또는 TPM 한도를 초과했습니다.
503no_workers_for_model현재 이 모델을 제공하는 Grid 워커가 없습니다.
503model_not_priced이 모델 티어의 요금이 아직 설정되지 않았습니다.
502engine_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에서 비슷한 모델을 고르거나, 프로바이더를 추가할 수 있도록 알려 주세요.

빠진 내용이 있나요? 요청이 이상하게 동작하면 /logs에 메모를 남겨 주세요. 가장 먼저 응답의 x_openalchemy.request_id를 여쭤봅니다.