API 指南

想知道這套 API 在實際服務中如何運作嗎? 您可以在以同一套引擎運作的 AI 八字應用程式 INTA – Life is Timing 中,親自體驗八字分析與 AI 對話。 INTA 就是這套 API 的實際運作範例。 INTA 的 AI 語音回應(TTS)也由同一套技術堆疊驅動 — 語音 API 將於日後公開。

快速入門

HRUM 提供會記憶的 AI、八字分析與 LLM 轉售。請依照以下 3 個步驟開始:

基本網址為 https://api.hrum.ai(API)與 https://console.hrum.ai(主控台)。舊網址 api.float.do、console.float.do、api.inta.do 仍可正常使用,若已完成串接則無須更改。

  1. 取得 API 金鑰 - 在主控台註冊後,於 API 金鑰畫面中建立金鑰(金鑰僅在建立後顯示一次)。從註冊到錯誤處理的完整流程,請參閱開發者入門指南。
  2. 發送請求 - 依照下方範例發送 POST 請求。
  3. 處理回應 - 從 JSON 回應中取出八字資料。
curl -X POST https://api.hrum.ai/api/v1/partners/v1/manseryeok \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "year": 1990,
    "month": 1,
    "day": 15,
    "hour": 14,
    "minute": 30,
    "timezone": "Asia/Seoul",
    "gender": "male"
  }'

注意 User-Agent: Python 標準函式庫 urllib 的預設 User-Agent(Python-urllib/3.x)會觸發安全規則,回傳 403(error 1010)。requests、OpenAI SDK、Node、curl 皆可正常運作。若使用 urllib 或自行開發的 HTTP 用戶端,請自行設定 User-Agent: <app-name>/<version> 標頭。 (實測:python-requests 通過、OpenAI/Python 通過、node 通過、Python-urllib 403)

節省費用 — 請儲存結果並重複使用。 每一筆成功的請求都會個別計費。萬年曆、紫微斗數、合盤、占星、終身八字的結果,只要出生年月日時與選項相同,再次呼叫也會得到相同結果,因此請將第一次的回應存入資料庫(例如以請求本文的雜湊值為鍵),之後直接使用已儲存的值。今日運勢、運勢走勢這類會隨日期變動的結果,請把日期也放進鍵中。詳情請參閱冪等性。

API 參考文件

HRUM 提供會記憶的 AI、八字分析與 LLM 轉售。

RIDM Memory API

為每位終端使用者託管對話記憶,並為 ridm/* 模型加上記憶層。記憶僅限 ridm/*,OpenAI/Google 模型則原樣轉售 — 同一個模型,不同的產品。也支援自動插入 YouTube 字幕。

沒有工作階段 — 一個永不結束的工作階段。 以相同的 user 呼叫,對話就會一直延續下去。每次呼叫時,伺服器會自動附上最近 historyCount 則對話輪次與 recallCount 則長期記憶(摘要、個人資料、記住的事實、持續中的煩惱),因此您只需傳送一則新訊息。要往回參照多遠,由這兩個數值調整;每位終端使用者可儲存的訊息數上限則由 memoryCap 設定。若想自行管理歷史紀錄,請省略 historyCount,並依 OpenAI 的方式把先前的對話放進 messages 一起傳送。

對話再長,費用也不會線性增加。 較舊的助理輪次會自動壓縮 — 最近 2 輪保留原文,更早的輪次則從 500 字逐步縮減為 200 字,以節省輸入 token(使用者輪次維持原樣)。此外,當使用者詢問過去的發言(例如「你上次說過~」)時,伺服器會搜尋已儲存的實際對話,並附上日期與說話者加以引用(包含在 recalledMemories 中);若沒有紀錄,則不會捏造,而是直接回答沒有紀錄。

LLM API(轉售)與 RIDM Memory API 的差異

同一個模型,不同的產品 — 只有前綴不同,其餘完全相同。回應中若附有 recalledMemories 與 memorySaved,代表走的是 RIDM 路徑。

功能 LLM API(轉售) RIDM Memory API
模型選擇 openai/*、google/*、anthropic/* 等 ridm/*(加上前綴)
回應格式 原始模型回應原樣傳回(相容 OpenAI) 原始模型回應+記憶欄位
user 參數 忽略 必填(endUserId,用於保留記憶)
對話記憶、摘要、個人資料回想 ✗ ✓(recallCount、memoryCap)
文件處理 僅限以 fileIds 明確插入 fileIds 明確指定+自動回想
YouTube 連結處理 支援 youtube:true 支援 youtube:true
情緒分析(emotion) 忽略(但若在主控台關閉情緒功能的帳號傳送 emotion:true,無論模型為何都會回傳 403 FEATURE_DISABLED) ✓(含摘要週期)
內容審核 僅 user 訊息 system+user 訊息
systemPrompt 限制 忽略 — 轉售模型會忽略 systemPrompt,請以 {"role":"system"} 放進 messages 驗證 8,000 字上限(僅限 ridm)
回應額外欄位 costUsd、costWon(費用) costWon、recalledMemories、memorySaved、memoryCapReached、filesRecalled、emotion、customProfile
價格 成本 × 匯率 × 1.10 轉售價 × 1.30(記憶保留、回想、情緒、檔案自動回想全部包含,不另按功能計費)
例外 — ridm/saju-report:無記憶 → 僅收轉售利潤,無法用於 chat(報告專用)

程式碼範例比較

// LLM API (resale) — no memory
{
  "model": "openai/gpt-5.6-terra",
  "messages": [{ "role": "user", "content": "..." }]
}

// RIDM Memory API — with the memory engine
{
  "model": "ridm/gpt-5.6-terra",  // only the prefix differs
  "user": "user_123",              // required (keeps memory)
  "messages": [{ "role": "user", "content": "..." }]
}

// Difference in the response
// Resale: { "id": "...", "choices": [...], "usage": {...}, "costWon": 1, "costUsd": 0.00045 }
// RIDM: { "id": "...", "choices": [...], "usage": {...}, "costWon": 2, "recalledMemories": [...], "memorySaved": { "id": "turn-...", "keywords": [] } }

POST /api/v1/partners/v1/chat/completions

具備記憶的對話式 LLM 呼叫。以相同的 user/endUserId 呼叫時,會保留過去的上下文。

請求參數

參數 型別 必填 說明
model string O 模型名稱。RIDM:ridm/gpt-5.6-terra 等 / 轉售:openai/gpt-5.2、google/gemini-3.5-flash 等
user string O 由合作夥伴核發的終端使用者 ID(endUserId — 值相同即保留記憶)
messages array O OpenAI 格式的訊息陣列 [{ "role": "user", "content": "..." }, ...]
systemPrompt string 系統指示(選填,最多 8,000 字 — 僅限 ridm/*)。轉售模型會忽略 systemPrompt,請以 {"role":"system"} 放進 messages。
youtube boolean 設為 true 時,自動插入最後一則訊息中 YouTube 連結的字幕
stream boolean 是否以串流回應(預設:false)。格式請參閱下方的串流(SSE)格式 — 並非 OpenAI 的 chunk 格式。
fileIds string[] 要插入的已上傳文件 ID(UUID,最多 5 個)。請參閱文件處理 API
emotion boolean 情緒狀態分析(僅限 ridm/*,預設 false)。請參閱情緒狀態分析
summaryEvery integer 摘要、情緒的更新週期(以輪次為單位,1–20,預設 5,僅限 ridm/*)
temperature number 0–2。不會傳給推理專用模型(無法關閉推理的模型)
top_p number 0–1
presence_penalty / frequency_penalty number 各為 -2–2
seed / stop number / string|string[] 以與 OpenAI 相同的意義傳給上游
response_format object OpenAI 格式(使用 json_object 時,messages 或 systemPrompt 中須含有「JSON」一詞)。Claude 模型會忽略
tools / tool_choice / parallel_tool_calls array / string|object / boolean OpenAI 格式的函式呼叫。支援 OpenAI、Google 模型(含同名的 ridm/ 模型),Claude 模型會回傳 400 TOOLS_UNSUPPORTED_FOR_MODEL
n / stream_options — 為了相容 SDK 而接受,但會忽略(一律只回傳 1 個回應)
max_tokens number 最大輸出 token 數(1–8,192,超過時回傳 400)。gpt-5.1 以上與 5.4、5.5、5.6 系列,伺服器會關閉推理(reasoning_effort none)後呼叫,因此可取得所要求數量的本文。無法關閉推理的模型(gpt-5、gpt-5-mini、gpt-5-nano、gpt-6-astra、o3、o3-mini、o4-mini),伺服器會額外加上 1,500 token 的推理預算後呼叫,這些推理 token 也會按輸出計費。
historyCount number 由伺服器自動附上的最近對話輪次數(1–50)。設定後,messages 只需傳送新訊息。省略時伺服器不會附上歷史紀錄,只使用 messages 的最後 10 則。
recallCount number 要回想多少則與問題相關的長期記憶(過去的摘要)(0–20,預設 3)。個人資料、記住的事實、持續中的煩惱一律包含在內。
memoryCap number 每位終端使用者的儲存訊息數上限(10–1000,預設 100)。每次請求時套用,不會固定保存。儲存的訊息數超過上限時,本輪仍會儲存,但回應會附上 memoryCapReached: true 與 memorySaved: null。
candor string 直言度 — 回答的直接程度。t / f(預設)。僅限 ridm/*,轉售模型會忽略。請參閱直言度(暫定名稱)

直言度(暫定名稱) — candor

即使是同樣的八字、同樣的問題,每個人想聽到的說法也不盡相同。candor 決定回答要多直接。在 RIDM Memory API(ridm/*)與三種八字解讀 API(解讀、解讀記憶、報告)中都以相同方式運作。

  • f(F 型) — 預設值。不做任何改變,與不傳送此欄位相同。
  • t(T 型) — 直言型。在第一段明確說出坦率的判斷,最後點出現在可以採取的行動。不會責備對方,也不會做出宿命論式的斷言。

舊值也持續接受:blunt → t,balanced 與 gentle → f(gentle 不再是獨立的直言度)。

它與 tone(敬語、半語、正式)是不同的軸,可以同時使用。例:tone: "formal"+candor: "t"=禮貌但直接的回答。

systemPrompt 與 persona 優先。若與角色設定中的語氣、禁止事項、格式衝突,則以後者為準。

若在使用者訊息中偵測到危機訊號(包含安全檢查失敗的情況),直言度會自動回到 f。只有以 t(或 blunt)傳送 candor 的請求,回應才會附上 candorApplied(實際套用的值,t | f),像這樣被改回時會顯示為 "f"。即使以舊值傳送,candorApplied 也會以 t/f 回傳。

用於直言度指示的 token 不計費。對話紀錄(RIDM Memory)只會儲存使用者傳送的原文。轉售模型(openai/* 等)會忽略此欄位。傳送不允許的值(例:"off"、"harsh")會回傳 400。

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/chat/completions \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ridm/gpt-5.6-terra",
    "user": "member-1024",
    "messages": [
      { "role": "user", "content": "Can we pick up where we left off about changing jobs?" }
    ]
  }'

回應範例

{
  "id": "chatcmpl-123",
  "object": "chat.completion",
  "created": 1629292800,
  "model": "ridm/gpt-5.6-terra",
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "안녕하세요! 이전 대화를 기억하고 있어요..."
      },
      "finish_reason": "stop",
      "index": 0
    }
  ],
  "usage": {
    "prompt_tokens": 1250,
    "completion_tokens": 320,
    "prompt_tokens_details": { "cached_tokens": 0 }
  },
  "costWon": 45,
  "recalledMemories": [...],
  "memorySaved": { "id": "turn-1756200000000", "keywords": [] },
  "youtubeUsed": ["abc123def45"]
}

usage 中沒有 total_tokens — 回傳的是 prompt_tokens、completion_tokens、prompt_tokens_details.cached_tokens,推理模型另有 completion_tokens_details.reasoning_tokens(已包含在 completion_tokens 中)。memorySaved 為已儲存輪次的資訊物件或 null(超過上限、工具呼叫的輪次),youtubeUsed 為已插入字幕的影片 ID 陣列(不是 URL)。

串流(SSE)格式

當 stream: true 時,回應不是 OpenAI 的 chunk 格式,而是以具名的 SSE 事件傳送。因此無法用 OpenAI SDK 的串流解析器讀取 — 請自行解析 SSE(非串流回應則相容 OpenAI)。

事件 data
event: chunk RIDM:{"delta":"…"}(工具呼叫時包含 tool_calls 片段) / 轉售:上游 chunk 物件原樣傳回
event: message_done RIDM:{finish_reason, usage, costWon, recalledMemories, memorySaved, memoryCapReached, emotion?, customProfile?, budgetExceeded?, tool_calls?} / 轉售:{finish_reason, usage, costUsd, costWon, budgetExceeded?}。沒有 id、choices、model
event: error {message, code, status} — 由於標頭(200)已送出,實際的錯誤狀態請以 status 確認
data: [DONE] 正常結束標記(最後一行)
event: chunk
data: {"delta":"안녕하세요"}

event: message_done
data: {"finish_reason":"stop","usage":{"prompt_tokens":1250,"completion_tokens":320,"prompt_tokens_details":{"cached_tokens":0}},"costWon":45,"recalledMemories":[],"memorySaved":{"id":"turn-1756200000000","keywords":[]}}

data: [DONE]

錯誤代碼

除了共通錯誤之外,此 API 會回傳以下代碼。stream: true 時,回應開始後發生的錯誤會以 event: error({message, code, status})傳送。轉售模型也適用同一張表。

代碼 HTTP 說明
MODERATION_FLAGGED400遭內容審核封鎖(ridm:system+user,轉售:user 訊息)
INSUFFICIENT_BALANCE402餘額不足(會先預留所要求的完整輸出再檢查)
MODEL_NOT_FOUND400未設定的模型
INVALID_TOOLS / TOOLS_UNSUPPORTED_FOR_MODEL400tools 相關欄位不一致 / 對 Claude 模型要求工具呼叫
FILE_NOT_FOUND400fileIds 中含有不存在的檔案(或其他合作夥伴的檔案)
FEATURE_DISABLED403在已關閉 youtube、files、emotion 功能的帳號中使用該選項
RATE_LIMITEDHTTP 400,本文 status 429上游速率限制,或超過轉售每日支出上限(每個合作夥伴預設 ₩100,000/日)
UPSTREAM_TIMEOUTHTTP 400,本文 status 504上游回應逾時(60 秒)
UPSTREAM_INVALID_REQUEST400上游模型拒絕請求(上游 400、422)
INVALID_RESPONSE_FORMAT400使用 response_format: json_object,但訊息中沒有「json」一詞(OpenAI 系列)
REPORT_ONLY_MODEL400指定了 ridm/saju-report — 僅限八字報告 API使用
(無)400ridm/* 模型缺少 user、systemPrompt 超過 8,000 字、不支援的模型前綴
provider_not_configured503目前未連接 Claude 模型

注意事項

自訂個人資料(Custom Profile)

僅限 ridm/* 模型。 為每位終端使用者儲存並管理任意的欄位名稱與值。可以儲存自動擷取的欄位值、由合作夥伴直接指定值,或將特定欄位放入本輪的提示中。值會累積保存,即使結構描述變更,既有的值也會保留(soft-update)。

請求參數(POST /api/v1/partners/v1/chat/completions)

參數 型別 說明
extractProfileFields string[] 要從對話中自動擷取的欄位名稱陣列(最多 100 個)。在摘要週期中,LLM 會將使用者的特徵、偏好、狀況分類到這些欄位名稱後儲存。擷取值為空或 null 時會略過並保留既有的值(累積制,手動指定的值不會被擷取值覆寫)。不另外計費。
injectProfileFields string[] 要放入本輪提示的欄位名稱陣列。只會插入指定的欄位,不會自動插入。 插入的欄位每一輪都會以輸入 token 計費。請只選擇需要的欄位。
endUserProfile object 欄位名稱與值的物件。例:{ "name": "Jane Kim", "age": "35", "interest": "parenting" }。指定的值會覆寫擷取的值。最多 100 個欄位,每個值預設 150 字(最多 500 字)。
profileValueMaxChars number 值的最大字數(預設 150,最多 500 — 超過的值會調整為 500)。僅套用於該次請求中儲存的值(endUserProfile 與本次摘要週期擷取的值),且不會被保存,因此每次請求都須重新傳送。

請求範例(RIDM chat)

{
  "model": "ridm/gpt-5.6-terra",
  "user": "enduser_123",
  "messages": [
    { "role": "user", "content": "Help me plan my kid's birthday party tomorrow" }
  ],
  "extractProfileFields": ["childAge", "interests", "budget", "constraints"],
  "injectProfileFields": ["name", "childAge", "interests"],
  "endUserProfile": {
    "name": "Jane Kim",
    "childAge": "7",
    "interests": "science, art"
  },
  "profileValueMaxChars": 200
}

回應中的個人資料

傳送了個人資料參數的請求,其回應(串流時為 message_done)會附上 customProfile 欄位。

"customProfile": {
  "injected": ["name", "childAge", "interests"],  // fields injected into this turn's prompt
  "stored": 4,                                     // number of fields currently stored
  "extractPending": ["budget"]                     // extraction targets that have no value yet
}

刪除 API

若要刪除特定欄位,請傳送 DELETE 請求:

DELETE /api/v1/partners/v1/profile/{endUserId}/field/{key}
X-Partner-Api-Key: your-api-key

回應:{ "success": true, "data": { "deleted": true } } — 即使是不存在的鍵或第一次出現的 endUserId,也會回傳 200 與 "deleted": false(不會建立新的終端使用者)。此 API 沒有專屬的錯誤代碼,只會回傳共通錯誤。

上限與限制

LLM API(轉售)

轉售 openai/*、google/* 等原始 LLM 模型(無記憶,原始回應原樣傳回)。轉售模型的請求中,user、systemPrompt、recallCount、memoryCap、summaryEvery、emotion、candor 會被忽略(系統指示請以 {"role":"system"} 放進 messages),回應中也不會有記憶欄位(recalledMemories 等)。價格=成本 × 匯率 × 1.10。

提供的模型(與 GET /api/v1/partners/v1/models 相同的清單)

curl https://api.hrum.ai/api/v1/partners/v1/models \
  -H "X-Partner-Api-Key: your-api-key"

GET /api/v1/partners/v1/models 的回應 — 並非 OpenAI 的 models.list 格式。價格為每 1M token 的韓元(₩),下方數字僅為範例。Claude 模型只有在伺服器已設定時才會出現在清單中。

{
  "success": true,
  "data": {
    "models": [
      { "modelId": "openai/gpt-5.6-terra", "upstream": "gpt-5.6-terra", "provider": "openai", "input_cost_krw": 1234, "output_cost_krw": 9876, "category": "base" },
      { "modelId": "ridm/gpt-5.6-terra", "upstream": "gpt-5.6-terra", "provider": "openai", "input_cost_krw": 1604.2, "output_cost_krw": 12838.8, "category": "ridm" }
    ]
  }
}

此 API 沒有專屬的錯誤代碼,只會回傳共通錯誤。免費。

Claude 模型(anthropic/*、ridm/claude-*)

  • 模型(13 款): anthropic/claude-fable-5-1 · anthropic/claude-opus-5-5 · anthropic/claude-sonnet-5-5 · anthropic/claude-haiku-5-5 · anthropic/claude-fable-5 · anthropic/claude-opus-5 · anthropic/claude-sonnet-5 · anthropic/claude-opus-4-8 · anthropic/claude-opus-4-7 · anthropic/claude-opus-4-6 · anthropic/claude-opus-4-5 · anthropic/claude-sonnet-4-6 · anthropic/claude-haiku-4-5(轉售) / 在相同名稱前加上 ridm/ 前綴即為 RIDM Memory API(轉售價 × 1.3)。
  • 請求格式不變: 以 OpenAI 格式傳送,伺服器會轉換為 Claude 格式後呼叫。即使有多則 system 訊息,也會合併為一則傳送。
  • 忽略 temperature、top_p: Claude 5.x 不接受取樣值,即使傳送也不會生效(不會產生錯誤)。回應語氣請以 system 提示調整。
  • max_tokens: 省略時為 8,192。Claude Fable 5、5.1 與 Opus 5、5.5 的內部推理一律開啟,推理 token 也會按輸出 token 計費;為避免回答被截斷,呼叫時會在要求的 max_tokens 上額外加上 1,500 token 的餘裕。
  • Haiku 5.5 長文區間: 單次請求的輸入超過 10 萬 token 時,Anthropic 官方價格會進入 ×5 區間,因此該請求的輸入、輸出 token 皆以 ×5 計費。
  • 支援範圍: 文字對話(含串流)。Claude 模型不支援工具呼叫(tools、tool_choice、parallel_tool_calls),會回傳 400 TOOLS_UNSUPPORTED_FOR_MODEL — OpenAI、Google 轉售模型則支援工具呼叫。不支援圖片輸入。

思考(推理)模型與 max_tokens: 使用隱藏思考(thinking/reasoning)的模型,思考 token 也會計入輸出上限。伺服器雖會加上餘裕後呼叫,但若 max_tokens 非常小(例:16),可能會以 finish_reason: "length" 回應且本文為空,上游已消耗的 token 仍會計費。建議最小值為 64 以上。適用模型:openai/gpt-5 · openai/gpt-5-mini · openai/gpt-5-nano · openai/gpt-6-astra · openai/o3 · openai/o3-mini · openai/o4-mini · anthropic/claude-opus-5 · anthropic/claude-opus-5-5 · anthropic/claude-fable-5 · anthropic/claude-fable-5-1 · google/gemini-3.1-pro(含加上 ridm/ 前綴的同名模型)。

思考餘裕與計費 token: 無法關閉思考的模型(openai/gpt-5 · openai/gpt-5-mini · openai/gpt-5-nano · openai/gpt-6-astra · openai/o3 · openai/o3-mini · openai/o4-mini · google/gemini-3.1-pro)與思考一律開啟的模型(anthropic/claude-opus-5 · anthropic/claude-opus-5-5 · anthropic/claude-fable-5 · anthropic/claude-fable-5-1)(含加上 ridm/ 前綴的同名模型),為確保能取得回答,伺服器會在要求的 max_tokens 上加上思考餘裕(最多 1,500 token)後呼叫。思考 token 也以輸出單價計費,因此實際計費的輸出 token 可能大於 max_tokens(例:max_tokens 200 的請求計費 828 token — 思考 747+本文 81)。若需嚴格限制費用上限,請使用 google/gemini-3.5-flash 這類可關閉思考的模型。

POST /api/v1/partners/v1/chat/completions

請求參數(無記憶層)

參數 型別 必填 說明
model string O ridm/gpt-5.6-terra(記憶) · 轉售為 openai/gpt-5.2、google/gemini-3.5-flash 等 — 完整清單請見價格頁面
messages array O OpenAI 格式的訊息
temperature number 0.0–2.0(省略時為模型預設值)。top_p(0–1)、presence_penalty 與 frequency_penalty(-2–2)、seed、stop、response_format,以及 tools、tool_choice、parallel_tool_calls 也以與 RIDM 相同的範圍接受(Claude 無法使用工具呼叫)
systemPrompt string 忽略 — 轉售模型會忽略 systemPrompt,請以 {"role":"system"} 放進 messages
fileIds string[] 要插入的文件 ID(UUID,最多 5 個,僅限明確插入)
max_tokens number 最大輸出 token 數(1–8,192,超過時回傳 400)。思考(推理)模型的思考 token 也會計入此上限,若設得太小(例:16),本文可能為空並回傳 finish_reason: "length",上游已消耗的 token 仍會計費。建議最小值為 64 以上。
emotion boolean 忽略(已關閉情緒功能的帳號傳送 emotion:true 時回傳 403 FEATURE_DISABLED)
summaryEvery number 忽略

使用範例(相容 OpenAI SDK)

const client = new OpenAI({
  apiKey: 'your-float-api-key',
  baseURL: 'https://api.hrum.ai/api/v1/partners/v1',
  defaultHeaders: { 'X-Partner-Api-Key': 'your-float-api-key' }
});

const response = await client.chat.completions.create({
  model: 'openai/gpt-5.6-terra',
  messages: [{ role: 'user', content: 'Hello' }]
});
// RIDM model example: model: 'ridm/gpt-5.6-terra'

回應

非串流回應為相容 OpenAI 的結構,再加上 costUsd、costWon、requestId。stream: true 並非 OpenAI 的 chunk 格式,因此無法用 OpenAI SDK 的串流解析器讀取 — 請參閱串流(SSE)格式自行解析。

{
  "id": "chatcmpl-1791452814000",
  "object": "chat.completion",
  "created": 1791452814,
  "model": "openai/gpt-5.6-terra",
  "usage": { "prompt_tokens": 9, "completion_tokens": 12, "prompt_tokens_details": { "cached_tokens": 0 } },
  "choices": [
    { "index": 0, "message": { "role": "assistant", "content": "Hello! How can I help?" }, "finish_reason": "stop" }
  ],
  "costUsd": 0.000162,
  "costWon": 1,
  "requestId": "resale-..."
}

錯誤代碼與 RIDM Memory API 的錯誤表相同。轉售模型也同時適用每日支出上限(RATE_LIMITED)。

AI 八字解讀 API

由生成式 AI 分析八字,提供量身打造的運勢解讀與建議。以 token 計費,只回傳解讀結果。

POST /api/v1/partners/v1/reading

根據八字產生 AI 八字解讀。內部的提示與理論不公開。

請求參數

參數 型別 必填 說明
speed string fast(預設,回應快速) | value(回應較慢,價格折扣 20%)
birth object birth 或 saju 擇一 {year, month, day, hour?, minute?, gender, calendar?}。calendar:solar(預設) | lunar — 農曆會先轉換為國曆再計算。出生地、時區、閏月(2026-10-17):以相同名稱、相同規則接受與萬年曆 API 相同的選填欄位 isLeapMonth、timezone、birthLatitude、birthLongitude、country、zaSiRule、birthTimePrecision,因此出生資料相同時,四柱會與萬年曆一致。座標必須兩個都傳送,只傳一個會回傳 400 INVALID_LOCATION。一個都不傳時,計算方式與以往完全相同(出生時刻以韓國時間計,農曆以非閏月計)。占星部分會依 timezone 取得該出生時刻實際使用的時間(含夏令時間)並搭配座標繪製星盤。無法辨識 birth.timezone 時,回應會附上 warnings(field: "birth.timezone")
saju object birth 或 saju 擇一 直接輸入四柱 {"year":{"stem":"경","branch":"오"},"month":{…},"day":{…},"hour"?:{…}}。與 birth 一起傳送時會交叉驗證,並以 saju 為優先(sajuMismatch)
year / month / day / gender number / string 平面欄位(舊版)。只有四個值全部齊備時,才會視為 birth(國曆)。birth、saju、平面欄位皆未提供時,回傳 400 MISSING_SUBJECT_INPUT
hour / minute number 出生時 0-23 / 分 0-59(選填)。省略 hour 時,會排除時柱,以年、月、日三柱為準進行解讀
question string O 關於運勢解讀的問題(例:「我的人生道路會怎麼走?」)
tone string 回應語氣("formal"、"casual"、"warm",預設值:"warm")
candor string 直言度 — 回答的直接程度。t / f(預設)。不計費。請參閱直言度(暫定名稱)
persona string 應用程式選定的角色(名稱、語氣、態度,最多 2,000 字)。只套用於語氣,不會優先於八字解讀、安全界線、長度指示。與問題一樣以輸入計費(字數 × 0.25)。若有多個角色,請從伺服器的允許清單中挑選後傳送 — 請勿直接放入瀏覽器傳來的文字
maxLength number 最大回應長度(100–2,000,預設值:800)
tools object 額外功能旗標。例:{"astrology": true, "youtube": true}。未知的鍵會回傳 400 UNKNOWN_TOOL
dream string 終端使用者描述的夢境內容(1–1,000 字)。傳送後,解夢會自動納入解讀中。請參閱納入項目
exclude string[] 要從納入項目中排除的項目。ziwei(紫微斗數) · astro(占星) · dream(解夢) · tarot(塔羅)。排除的項目,其依據與費用都會一併扣除。例:["ziwei", "astro"]。舊值 today 仍會接受,但沒有任何效果(今日運勢已不再是納入項目)
tarot object 傳送後,會抽出用於本次解讀的塔羅牌並一起解讀。選項與塔羅 API 相同:count(1–10)或 spread 擇一、reversed、seed。牌面語言依問題的語言而定。抽出的牌(含圖片網址)會放在回應的 tarot 中
only string 單獨呼叫八字 AI 中的其中一個 AI。saju · ziwei · astro · tarot · dream。與 exclude 一起傳送時回傳 400。請參閱單獨呼叫一個 AI

請求參數 — tools 選項

選項 型別 說明
astrology boolean 設為 true 時,將西洋占星的本命盤反映到解讀中。不另外計費
youtube boolean 設為 true 時,插入 question 中 YouTube 連結的字幕(以字幕字數 × 0.25 作為輸入計費)。不使用最上層的 youtube 欄位 — 必須放在 tools 中
fileIds string[] 要插入的文件 ID(UUID,最多 5 個)

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/reading \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Is this a good year to change jobs?",
    "birth": { "year": 1990, "month": 5, "day": 15, "hour": 14, "minute": 30, "gender": "female" },
    "maxLength": 600,
    "tone": "warm"
  }'

回應範例

{
  "success": true,
  "data": {
    "interpretation": "당신의 사주에서 보이는 특징은...",
    "sajuSource": "computed",
    "usage": {
      "inputTokens": 450,
      "outputTokens": 280
    },
    "costPoints": 18
  }
}

回應欄位

欄位 說明
interpretation解讀文字
sajuSourcecomputed(以 birth 計算) | provided(使用輸入的 saju)
sajuMismatch同時傳送 birth 與 saju 但柱不一致時的警告({pillars, computed, note}),其他情況為 null 或省略
toolsUsed實際執行的工具(例:["youtube"])
toolsSkipped有要求但被略過的工具 [{tool, reason}],reason:unavailable | cap_exceeded | error | auto_rejected
filesUsed已插入的文件 ID(使用 tools.fileIds 時)
usage參考用的 token 數(inputTokens 是包含八字、系統提示的實際值 — 並非計費依據)
costPoints實際扣款金額(₩)
modulesUsed實際納入的項目(例:["saju","ziwei","astro"],saju 排在最前面)。只有在納入項目功能開啟時才會附上
moduleFees各納入項目的固定費用(₩)(例:{"ziwei":50,"astro":20})。已包含在 costPoints 中。只有在納入項目功能開啟時才會附上
tarot納入塔羅時抽出的牌 — 與塔羅 API 回應的形式相同(含 cards[] 的 imageUrl,不含 question、costPoints)
only原樣傳回請求中的 only 值(僅在有傳送時)。only 不是 saju 時不會使用八字,因此沒有 sajuSource
support危機諮詢資訊 {message, contacts:[{name, number, hours}]}。若 dream 內容為危機表述,不會呼叫 AI,而是在 interpretation 中放入求助資訊,並以 costPoints: 0 回傳。無法完成安全檢查時也會附上

錯誤代碼

除了共通錯誤之外,此 API 會回傳以下代碼:

HTTP 代碼
400MISSING_SUBJECT_INPUT · INVALID_SAJU_PILLAR · INVALID_LUNAR_DATE · UNKNOWN_TOOL · INVALID_FILE_IDS · FILE_IDS_TOO_MANY · INVALID_FILE_ID_TYPE · FILE_NOT_FOUND · INVALID_TOOL_MODE · MEMORY_REQUIRES_MEMORY_ENDPOINT · EMOTION_REQUIRES_MEMORY · MISSING_ENDUSER_ID(記憶) · ONLY_WITH_EXCLUDE · ONLY_REQUIRES_INPUT · ONLY_DOMAIN_UNAVAILABLE · ONLY_INPUT_INVALID(單獨呼叫一個 AI)
402INSUFFICIENT_BALANCE — 呼叫前會先預留 maxLength × 2 token(value 等級或非韓文的問題另加 4,000)的輸出費用,因此即使最終金額較小,也可能遭到拒絕
403FEATURE_DISABLED — 使用了帳號中已關閉的功能(youtube、files、emotion)

納入項目 — 紫微斗數 · 占星 · 解夢 · 塔羅

八字 AI 中包含了八字、紫微斗數、占星、塔羅、解夢 AI。當日的日辰無須另外呼叫,就會預設反映在所有解讀中(不另收費)。以整合方式呼叫一次,就會以納入項目的計算結果為依據一起解讀;想排除的項目則以 exclude 排除。若只想呼叫需要的單一 AI,請使用 only。如果只需要計算結果,也可以透過計算型端點(/ziwei-chart · /astrology(占星全覽) · /dream · /tarot)逐一單獨呼叫相同的項目,自行打造應用程式。/reading/memory 也使用相同的欄位。

項目何時納入作為依據放入的內容費用(=單獨端點 1 次的價格)
紫微斗數 ziwei有出生年月日+出生時刻(hour)時預設納入命盤摘要 — 命宮、身宮、三方四正、生年四化、目前的大限、流年/ziwei-chart
占星 astro有出生年月日時預設納入(沒有時刻也可以)本命盤摘要 — 太陽、月亮、水星~土星的星座與度數、上升星座(可取得時)₩20(占星的單獨商品為 /astrology)
解夢 dream在 dream 中傳送夢境內容時夢境內容+從夢中找到的象徵詞/dream(沒有候選時為 0 韓元)
塔羅 tarot傳送 tarot 時本次請求抽出的牌及正、逆位的含義(連同圖片網址放在回應的 tarot 中)/tarot

請求範例(POST /api/v1/partners/v1/reading)

{
  "birth": { "year": 1990, "month": 5, "day": 15, "hour": 14, "gender": "female" },
  "question": "I can't stop thinking about last night's dream. What could it mean for me right now?",
  "dream": "큰 뱀이 집 안으로 들어와 내 발 옆에 똬리를 틀었어요",
  "tarot": { "spread": "past-present-future" }
}

回應範例

{
  "success": true,
  "data": {
    "interpretation": "뱀이 집 안으로 들어와 곁에 머무는 꿈은...",
    "sajuSource": "computed",
    "modulesUsed": ["saju", "dream", "ziwei", "astro", "tarot"],
    "moduleFees": { "dream": 30, "ziwei": 50, "astro": 20, "tarot": 20 },
    "tarot": {
      "lang": "ko",
      "count": 3,
      "spread": { "type": "past-present-future", "name": "과거·현재·미래", "description": "시간 흐름을 따라가는 질문", "positions": ["과거", "현재", "미래"] },
      "reversedAllowed": true,
      "seed": null,
      "cards": [
        { "position": 1, "positionLabel": "과거", "id": "wands_10", "name": "완드의 10", "nameEn": "Ten of Wands", "arcana": "wands", "reversed": true, "keywords": ["내려놓기", "위임", "해방"], "meaning": "무거운 짐을 마침내 내려놓거나 도움을 받기 시작하는 시기.", "imageUrl": "https://console.hrum.ai/tarot/cards/v2/wands_10.webp" }
      ],
      "cardBackUrl": "https://console.hrum.ai/tarot/cards/v2/back.webp"
    },
    "usage": {
      "inputTokens": 3140,
      "outputTokens": 760
    },
    "costPoints": 162
  }
}

只有八字(排除其他所有項目)(POST /api/v1/partners/v1/reading)

{
  "birth": { "year": 1990, "month": 5, "day": 15, "hour": 14, "gender": "female" },
  "question": "Is this a good year to change jobs?",
  "exclude": ["ziwei", "astro"]
}

單獨呼叫一個 AI — only

八字 AI 中包含了八字、紫微斗數、占星、塔羅、解夢 AI。除了像上面那樣整合呼叫一次之外,也可以用 only 單獨呼叫需要的一個 AI。該 AI 只會根據自己的依據(命盤、星盤、抽出的牌、解夢候選)作答,不會放入其他項目。

only呼叫的對象需要的輸入費用
saju八字 AI(不含其他項目,只有八字)birth 或 saju僅 token 價格(無固定費用)
ziwei紫微斗數 AIbirth+出生時刻(hour)token 價格+/ziwei-chart 1 次的價格
astro占星 AIbirth(沒有時刻也可以)token 價格+₩20(占星項目的固定費用)
tarot塔羅 AItarot 選項 — 不需要 birthtoken 價格+/tarot 1 次的價格
dream解夢 AIdream 夢境內容 — 不需要 birthtoken 價格+/dream 1 次的價格

請求範例 — 僅塔羅 AI(POST /api/v1/partners/v1/reading)

{
  "question": "Should I keep pushing ahead with the job change I'm preparing?",
  "only": "tarot",
  "tarot": { "spread": "past-present-future" }
}

回應範例

{
  "success": true,
  "data": {
    "interpretation": "과거 자리의 완드의 10 역방향은 오래 짊어진 짐을...",
    "only": "tarot",
    "modulesUsed": ["tarot"],
    "moduleFees": { "tarot": 20 },
    "tarot": {
      "lang": "ko",
      "count": 3,
      "spread": { "type": "past-present-future", "name": "과거·현재·미래", "description": "시간 흐름을 따라가는 질문", "positions": ["과거", "현재", "미래"] },
      "reversedAllowed": true,
      "seed": null,
      "cards": [
        { "position": 1, "positionLabel": "과거", "id": "wands_10", "name": "완드의 10", "nameEn": "Ten of Wands", "arcana": "wands", "reversed": true, "keywords": ["내려놓기", "위임", "해방"], "meaning": "무거운 짐을 마침내 내려놓거나 도움을 받기 시작하는 시기.", "imageUrl": "https://console.hrum.ai/tarot/cards/v2/wands_10.webp" }
      ],
      "cardBackUrl": "https://console.hrum.ai/tarot/cards/v2/back.webp"
    },
    "usage": {
      "inputTokens": 1180,
      "outputTokens": 720
    },
    "costPoints": 37
  }
}

注意事項

AI 八字解讀、記憶 API

為每位終端使用者託管對話記憶,在使用者再次造訪時延續過去的上下文進行解讀,提供個人化且持續的諮詢體驗。價格為 AI 八字解讀 token 單價的 1.3 倍(每 1M token:輸入 3,754 韓元、輸出 30,030 韓元 — 解讀為輸入 2,888 韓元、輸出 23,100 韓元,VAT 另計)。

POST /api/v1/partners/v1/reading/memory

根據每位終端使用者的記憶產生 AI 八字解讀。

請求參數

參數 型別 必填 說明
endUserId string O 由合作夥伴核發的終端使用者 ID(必須為唯一值)
speed string fast(預設,回應快速) | value(回應較慢,價格折扣 20%)
birth object birth 或 saju 擇一 {year, month, day, hour?, minute?, gender, calendar?}。calendar:solar(預設) | lunar — 農曆會先轉換為國曆再計算。出生地、時區、閏月(2026-10-17):以相同名稱、相同規則接受與萬年曆 API 相同的選填欄位 isLeapMonth、timezone、birthLatitude、birthLongitude、country、zaSiRule、birthTimePrecision,因此出生資料相同時,四柱會與萬年曆一致。座標必須兩個都傳送,只傳一個會回傳 400 INVALID_LOCATION。一個都不傳時,計算方式與以往完全相同(出生時刻以韓國時間計,農曆以非閏月計)。占星部分會依 timezone 取得該出生時刻實際使用的時間(含夏令時間)並搭配座標繪製星盤。無法辨識 birth.timezone 時,回應會附上 warnings(field: "birth.timezone")
saju object birth 或 saju 擇一 直接輸入四柱 {"year":{"stem":"경","branch":"오"},"month":{…},"day":{…},"hour"?:{…}}。與 birth 一起傳送時會交叉驗證,並以 saju 為優先(sajuMismatch)
year / month / day / gender number / string 平面欄位(舊版)。只有四個值全部齊備時,才會視為 birth(國曆)。birth、saju、平面欄位皆未提供時,回傳 400 MISSING_SUBJECT_INPUT
hour / minute number 出生時 0-23 / 分 0-59(選填)。省略 hour 時,會排除時柱,以年、月、日三柱為準進行解讀
question string O 關於運勢解讀的問題
tone string 回應語氣("formal"、"casual"、"warm",預設值:"warm")
candor string 直言度 — 回答的直接程度。t / f(預設)。不計費。請參閱直言度(暫定名稱)
persona string 應用程式選定的角色(名稱、語氣、態度,最多 2,000 字)。只套用於語氣,不會優先於八字解讀、安全界線、長度指示。與問題一樣以輸入計費(字數 × 0.25)。若有多個角色,請從伺服器的允許清單中挑選後傳送 — 請勿直接放入瀏覽器傳來的文字
tagFilter string[] 要搜尋的記憶標籤篩選條件(選填)
maxLength number 最大回應長度(100–2,000,預設值:800)
recallCount number 要回想的過去記憶數量(0–20,預設 3)
tools object 額外功能旗標。例:{"astrology": true}。未知的鍵會回傳 400 UNKNOWN_TOOL

請求參數 — tools 選項

選項 型別 說明
astrology boolean 設為 true 時,將西洋占星的本命盤反映到解讀中。不另外計費
fileIds string[] 要插入的文件 ID(UUID,最多 5 個)。省略時,會自動回想與問題標籤重疊的分析文件(filesRecalled)
emotion / summaryEvery boolean / integer 情緒狀態分析(回應 emotion) / 摘要、情緒的更新週期 1–20(預設 5)
youtube boolean YouTube 插入僅支援 /reading(/reading/memory 尚未支援) — 即使傳送也不會插入字幕

回應範例

{
  "success": true,
  "data": {
    "interpretation": "당신의 사주에서 보이는 특징은...",
    "sajuSource": "computed",
    "memory": {
      "used": true,
      "summaryInjected": false,
      "notesInjected": 2,
      "tags": ["직장"],
      "overheadTokens": 120
    },
    "usage": {
      "inputTokens": 750,
      "outputTokens": 380
    },
    "costPoints": 36,
    "toolsUsed": ["memory"]
  }
}

其他回應欄位(sajuMismatch、toolsSkipped、filesUsed)與 AI 八字解讀 API 相同;自動回想的文件會放在 filesRecalled,tools.emotion: true 時則會附上 emotion。計費依據(YouTube 除外)也與解讀 API 相同。

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/reading/memory \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "endUserId": "member-1024",
    "question": "About the job change we talked about last time: is next month a good time to make the move?",
    "birth": { "year": 1990, "month": 5, "day": 15, "hour": 14, "minute": 30, "gender": "female" }
  }'

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳以下代碼:

HTTP代碼發生時機
400MISSING_ENDUSER_IDendUserId 為空或只有空白
400MISSING_SUBJECT_INPUT · INVALID_SAJU_PILLAR · INVALID_LUNAR_DATE出生資料、八字輸入錯誤(與解讀 API 相同)
400UNKNOWN_TOOL · INVALID_TOOL_MODE · INVALID_FILE_IDS · FILE_IDS_TOO_MANY · INVALID_FILE_ID_TYPE · FILE_NOT_FOUNDtools、fileIds 錯誤。此路徑也接受 tools.emotion、tools.summaryEvery
400ONLY_WITH_EXCLUDE · ONLY_REQUIRES_INPUT · ONLY_DOMAIN_UNAVAILABLE · ONLY_INPUT_INVALID與單獨呼叫一個 AI 相關的錯誤
402INSUFFICIENT_BALANCE無法預先預留輸出費用(方式與解讀 API 相同)
403FEATURE_DISABLED使用了帳號中已關閉的功能(youtube、files、emotion)

記憶管理 API

AI 八字解讀記憶型(POST /reading/memory)與 RIDM 聊天(ridm/* 模型的 user)使用同一個終端使用者記憶儲存區。下方路徑中的 {endUserId} 就是當時傳送的值(例如將聊天按工作階段區分時,就是 memberId:chatId 這類完整的鍵)。

端點 方法 說明
/api/v1/partners/v1/memory/{endUserId} GET 查詢終端使用者已儲存的記憶 → {endUserId, summary, metaSummary, tags, profile, concerns, facts}(profile、facts 目前一律為 null / [])
/api/v1/partners/v1/memory/{endUserId}/messages GET 查詢終端使用者的訊息清單。查詢參數 limit(預設 50,最多 200)、offset → {endUserId, messages:[{id, role, content, tags, createdAt}], offset, limit, total}
/api/v1/partners/v1/memory/search?endUserId={endUserId}&tags=… GET 搜尋記憶標籤(tags 以逗號分隔,已包含在 RIDM 記憶價格中,不另外計費) → {endUserId, query:{tags}, results}(results 最多 20 筆)
/api/v1/partners/v1/memory/{endUserId}/turns POST 將已進行過的對話(例:AI 電話諮詢)不經 AI 生成直接儲存。本文 {messages:[{role, content}], summary?, tags?} — role 為 user、assistant,messages 1–50 則,content 最多 4,000 字,summary 最多 1,500 字,tags 最多 10 個(各 30 字)。依傳送順序儲存,tags 會附加到所有輪次。提供 summary 時,會顯示為 GET /memory/{endUserId} 的 summary。若為第一次出現的 endUserId 則會新建。由於沒有 AI 呼叫,不另外計費 → {endUserId, saved, summarySaved}(僅限伺服器金鑰)
/api/v1/partners/v1/memory/{endUserId} DELETE 刪除終端使用者的所有記憶,以及以該終端使用者上傳的檔案(/files) → 204(無本文)

請求、回應範例

# Get stored memory
curl https://api.hrum.ai/api/v1/partners/v1/memory/member-1024 \
  -H "X-Partner-Api-Key: your-api-key"

{
  "success": true,
  "data": {
    "endUserId": "member-1024",
    "summary": "이직을 고민 중이며 다음 달 면접을 앞두고 있다...",
    "metaSummary": "...",
    "tags": ["이직", "면접"],
    "profile": null,
    "concerns": ["..."],
    "facts": []
  }
}
# Message list (oldest first)
curl "https://api.hrum.ai/api/v1/partners/v1/memory/member-1024/messages?limit=2&offset=0" \
  -H "X-Partner-Api-Key: your-api-key"

{
  "success": true,
  "data": {
    "endUserId": "member-1024",
    "messages": [
      { "id": "...", "role": "user", "content": "이직 고민이 있어요", "tags": ["이직"], "createdAt": "2026-10-11T09:00:00.000Z" },
      { "id": "...", "role": "assistant", "content": "...", "tags": [], "createdAt": "2026-10-11T09:00:04.000Z" }
    ],
    "offset": 0,
    "limit": 2,
    "total": 18
  }
}
# Tag search (tags as stored: 이직 = job change, 면접 = interview)
curl "https://api.hrum.ai/api/v1/partners/v1/memory/search?endUserId=member-1024&tags=이직,면접" \
  -H "X-Partner-Api-Key: your-api-key"

{
  "success": true,
  "data": {
    "endUserId": "member-1024",
    "query": { "tags": ["이직", "면접"] },
    "results": [
      { "id": "...", "summary": "다음 달 면접 일정을 이야기함", "level": 0, "tags": ["면접"], "createdAt": "2026-10-11T09:00:00.000Z" }
    ]
  }
}
# Save a conversation (no AI generation)
curl -X POST https://api.hrum.ai/api/v1/partners/v1/memory/member-1024/turns \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      { "role": "user", "content": "I'\''m worried about my interview next month" },
      { "role": "assistant", "content": "You'\''ve prepared well. You'\''ll do fine." }
    ],
    "summary": "Call about feeling anxious before next month'\''s interview",
    "tags": ["interview"]
  }'

{
  "success": true,
  "data": {
    "endUserId": "member-1024",
    "saved": 2,
    "summarySaved": true
  }
}
# Delete everything (memory + uploaded files) — 204, no body
curl -X DELETE https://api.hrum.ai/api/v1/partners/v1/memory/member-1024 \
  -H "X-Partner-Api-Key: your-api-key"

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳以下代碼:

HTTP代碼發生時機
404END_USER_NOT_FOUND第一次出現的 endUserId(除了儲存對話以外的四個路徑共通)
400MISSING_PARAM搜尋 — 缺少 endUserId
400MISSING_TAGS搜尋 — tags 為空
400ENDUSER_ID_TOO_LONG儲存對話 — endUserId 超過 255 字

注意事項

八字報告 API

不需要提問,按一下按鈕就能一次取得所有八字解讀,從總評、財運、感情到大運。這是與對話型(reading)分開、單次付款的商品。預設使用專用模型 ridm/saju-report(RIDM 自家的報告特化模型 — 由於是單次商品,不搭載記憶)。解讀 API 的回應上限為 2,000 字 — 若需要更長的詳細解說(最多 12 節,約 6,000 字),請使用此報告 API。

POST /api/v1/partners/v1/reading/report

輸入出生年月日(或八字),即可取得依章節分段的 Markdown 八字報告。

請求參數

參數 型別 必填 說明
birthobjectbirth 或 saju 擇一{year, month, day, hour?, minute?, gender, calendar?} — calendar: "lunar" 會先轉換為國曆再計算。出生地、時區、閏月(2026-10-17):以相同名稱、相同規則接受與萬年曆 API 相同的選填欄位 isLeapMonth、timezone、birthLatitude、birthLongitude、country、zaSiRule、birthTimePrecision,因此出生資料相同時,四柱會與萬年曆一致。座標必須兩個都傳送,只傳一個會回傳 400 INVALID_LOCATION。一個都不傳時,計算方式與以往完全相同(出生時刻以韓國時間計,農曆以非閏月計)。占星部分會依 timezone 取得該出生時刻實際使用的時間(含夏令時間)並搭配座標繪製星盤。無法辨識 birth.timezone 時,回應會附上 warnings(field: "birth.timezone")
sajuobjectbirth 或 saju 擇一直接輸入四柱 {"year":{"stem":"경","branch":"오"},"month":{…},"day":{…},"hour"?:{…}}
year / month / day / gendernumber / string選填平面欄位(舊版,國曆)。只有四個值全部齊備時才視為 birth。birth、saju 皆未提供時回傳 400 MISSING_SUBJECT_INPUT
hour / minutenumber選填省略 hour 時,會排除時柱,以年、月、日三柱為準進行解讀。未提供 hour 而只傳送 minute 時會被忽略
tonestring選填warm(預設) | casual | formal
candorstring選填直言度 — t | f(預設)。只會改變優點與困難點的安排與強度,章節結構以及不對醫療、法律、投資做出確切答覆的限制維持不變。不計費。請參閱直言度(暫定名稱)
personastring選填語氣、角色指示(最多 2,000 字 — 只有這部分的長度以輸入計費)
sectionsstring[]選填章節標題清單(1–12 個,每個標題最多 30 字)。預設 8 個:총평(總評)、타고난 기질(天生氣質)、재물운(財運)、연애·인연(感情、緣分)、직업·적성(職業、適性)、올해와 내년(今年與明年)、10년 대운 흐름(10 年大運走勢)、마지막 한 줄 처방(最後一句建議)

報告一律以韓文撰寫。傳送 speed、tools、lang、question 等上表中沒有的欄位時,會以 400 拒絕。

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/reading/report \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "birth": { "year": 1990, "month": 5, "day": 15, "hour": 14, "minute": 30, "gender": "female" },
    "sections": ["총평", "재물운", "연애·인연"]
  }'

回應

{
  "success": true,
  "data": {
    "report": "## 총평\n...",        // full Markdown, section by section
    "sections": ["총평", "..."],
    "sajuSource": "computed",
    "usage": { "inputTokens": 5756, "outputTokens": 2019 },
    "costPoints": 77,
    "model": "ridm/saju-report"
    // "candorApplied": "t"  — only when candor was sent as t (t | f)
  }
}

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳以下代碼:

HTTP代碼發生時機
400MISSING_SUBJECT_INPUTbirth、saju 皆未提供
400INVALID_SAJU_PILLARsaju 的柱不屬於六十甲子
400INVALID_LUNAR_DATE不存在的農曆日期
402INSUFFICIENT_BALANCE無法預先預留報告最大長度(6,000 token)的輸出費用

YouTube 摘要 API

擷取 YouTube 影片的字幕,提供摘要與 Q&A 分析。沒有字幕時回傳 400 錯誤(不計費)。

POST /api/v1/partners/v1/youtube/summary

請求參數

參數 型別 必填 說明
url string O YouTube 網址(例:https://www.youtube.com/watch?v=dQw4w9WgXcQ)或 11 碼影片 ID
question string 特定問題(選填 — 有提供時為 Q&A 模式)
maxLength number 摘要長度目標(100–4,000,預設 1,000)。作為輸出 token 預算使用,不保證精確的字數
tone string 語氣選擇:warm | casual | formal(預設:casual)。在 question(Q&A)模式下會被忽略
lang string 字幕查詢語言(預設:ko)。摘要(無 question)不論語言為何,一律以韓文撰寫。question(Q&A)模式則可以用問題的語言回答

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/youtube/summary \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "maxLength": 1000 }'

回應範例

{
  "success": true,
  "data": {
    "summary": "## 0:00~1:30 오프닝\n영상 제목 설명...\n\n## 1:30~5:00 본론\n...",
    "video": {
      "videoId": "dQw4w9WgXcQ",
      "title": "Video Title",
      "channel": "Channel Name"
    },
    "transcriptSource": "supadata",
    "usage": {
      "promptTokens": 7059,
      "completionTokens": 1384
    },
    "costPoints": 51,
    "model": "ridm/gpt-5.6-terra"
  }
}

注意事項

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳以下代碼:

HTTP代碼發生時機
400INVALID_YOUTUBE_URL無法從 URL 找到影片 ID
400TRANSCRIPT_UNAVAILABLE沒有字幕的影片(不計費)
400LLM_GENERATION_FAILED摘要產生失敗或結果為空
402INSUFFICIENT_BALANCE無法預先預留摘要費用
403FEATURE_DISABLED帳號中已關閉 YouTube 功能

開啟與關閉功能

YouTube 摘要 API 可依合作夥伴帳號及請求單位選擇啟用。在主控台的「功能設定」中管理全域啟用狀態;chat 需明確指定最上層的 youtube:true,reading 則需明確指定 tools: { "youtube": true },以按請求啟用。

文件處理 API

可上傳 PDF、Word(.docx)、Excel(.xlsx)、PowerPoint(.pptx)、CSV、純文字、Markdown、Hangul(.hwpx)文件,並以 AI 分析後存入以上下文為基礎的知識庫。文件會自動擷取內容;啟用「AI 分析」選項時,會將文件按上下文切分,並為每個區段產生摘要與搜尋標籤後儲存。

支援格式與限制

項目 規格
支援格式 .pdf、.docx、.xlsx、.pptx、.csv、.txt、.md、.hwpx(不支援 Hangul 舊版的 .hwp)
最大檔案大小 10 MB
最大擷取文字量 200,000 字(超過時標示 charsCapped: true)
每次請求的最大檔案數 5 個(fileIds)
chat 插入大小 每個檔案最多 40,000 字 / 合計 80,000 字
分析區塊範圍 3–8 個區段(40,000 字以上的長文件分 2 次處理)
標籤範圍 每個區段最多 10 個標籤,全部合計最多 10 個

端點

方法 路徑 說明
POST /api/v1/partners/v1/files 上傳檔案(multipart)
GET /api/v1/partners/v1/files 查詢檔案清單(合作夥伴範圍)。查詢參數 endUserId、limit(預設 20,最多 100)、offset → {files, total, limit, offset}
GET /api/v1/partners/v1/files/:id 查詢檔案詳細資料(含擷取的文字)
DELETE /api/v1/partners/v1/files/:id 刪除檔案

上傳檔案

POST /api/v1/partners/v1/files

以 Multipart form 格式上傳檔案。

請求欄位

欄位 型別 必填 說明
file binary O 要上傳的檔案
endUserId string 終端使用者 ID(分析時必填)
analyze 'true'|'false' 啟用 AI 分析(預設:'false')

cURL 範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/files \
  -H "X-Partner-Api-Key: YOUR_API_KEY" \
  -F "[email protected]" \
  -F "endUserId=user_123" \
  -F "analyze=true"

回應範例

{
  "success": true,
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "name": "sample.pdf",
    "originalName": "sample.pdf",
    "mime": "application/pdf",
    "size": 125000,
    "textLength": 8942,
    "charsCapped": false,
    "textPreview": "1장. 개요 ...",
    "summary": "문서 전체 요약...",
    "context": "문서 전체 요약...",
    "status": "analyzed",
    "analysisStatus": "analyzed",
    "analyzeRequested": true,
    "endUserId": "user_123",
    "usage": { "inputTokens": 3100, "outputTokens": 420, "costWon": 1 },
    "totalChunks": 3,
    "createdAt": "2026-08-26T12:34:56Z"
  }
}

清單、詳細資料、刪除

# List — newest first, limit 1–100 (default 20)
curl "https://api.hrum.ai/api/v1/partners/v1/files?endUserId=user_123&limit=20&offset=0" \
  -H "X-Partner-Api-Key: YOUR_API_KEY"

{
  "success": true,
  "data": {
    "files": [ { "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "name": "sample.pdf", "status": "analyzed", ... } ],
    "total": 1,
    "limit": 20,
    "offset": 0
  }
}
# Details — upload response fields + extractedText + chunks
curl https://api.hrum.ai/api/v1/partners/v1/files/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H "X-Partner-Api-Key: YOUR_API_KEY"

{
  "success": true,
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "name": "sample.pdf",
    ...,
    "extractedText": "1장. 개요 ...",
    "chunks": [
      { "id": "...", "chunkIndex": 0, "context": "1장 요약...", "tags": ["개요"], "textLength": 2980 }
    ]
  }
}
# Delete
curl -X DELETE https://api.hrum.ai/api/v1/partners/v1/files/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H "X-Partner-Api-Key: YOUR_API_KEY"

{ "success": true, "data": { "deleted": true } }

與 Chat 及解讀串接

明確附加: 在 Chat completions 或 AI 解讀請求中,可用 fileIds 參數插入最多 5 份文件。已分析的檔案會插入文件摘要(最多 500 字)與原文文字,未分析的檔案則插入原文文字(原文限制為每個檔案 40,000 字 / 合計 80,000 字,不插入子區塊)。插入的文件會附加到最後一則使用者訊息,並計入輸入 token。轉售模型只支援以 fileIds 明確插入。

自動回想(僅限 ridm/*): 在 ridm/* chat 與 reading-memory 模型中,會自動搜尋並插入與使用者問題標籤重疊的已分析檔案(僅在未明確指定 fileIds 時)。回應中會以 filesRecalled 陣列顯示回想到的檔案 ID。

Chat 請求範例

{
  "model": "ridm/gpt-5.6-terra",
  "messages": [
    { "role": "user", "content": "Can you summarize the main points of this document?" }
  ],
  "fileIds": ["f47ac10b-58cc-4372-a567-0e02b2c3d479"],
  "user": "user_123"
}

回應範例

{
  "id": "chatcmpl-abc123",
  "choices": [{
    "message": { "content": "문서의 주요 내용은..." },
    "finish_reason": "stop"
  }],
  "usage": { "prompt_tokens": 2500, "completion_tokens": 150 },
  "filesUsed": ["f47ac10b-58cc-4372-a567-0e02b2c3d479"]
}

filesRecalled 只有在有自動回想的檔案時才會附上(為空時省略)。

價格與計費

開啟與關閉功能

文件處理功能可在合作夥伴帳號層級啟用或停用。在主控台的「功能設定」中管理,停用時所有檔案請求都會回傳 403。

分析狀態與區塊

GET /api/v1/partners/v1/files/:id 的回應包含 analysisStatus、extractedText、chunks。只有在分析完成且 totalChunks 為 2 以上時,chunks 才會是陣列(每個區塊:chunkIndex、context(摘要)、tags 最多 10 個),其他情況則為 null。上傳回應中沒有 chunks。

狀態 說明
ready 擷取完成、未分析(analyze=false 或未指定 — analyzeRequested=false)
analyzing 分析進行中(超過 30,000 字時為非同步)
analyzed 分析完成(含 context、tags、chunks[])
analyze_failed 分析失敗(回應中不包含失敗原因 — 請重新上傳)

注意事項

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳以下代碼:

HTTP代碼發生時機
400FILE_NOT_PROVIDED上傳 — 沒有 file 部分
400INVALID_FILE_TYPE上傳 — 不支援的格式
400FILE_TOO_LARGE上傳 — 超過 10MB(視情況可能回傳不含代碼的 413)
400END_USER_REQUIRED上傳 — analyze=true 但沒有 endUserId
400(無)詳細資料、刪除 — :id 不是 UUID
402INSUFFICIENT_BALANCE上傳 — 無法預先預留分析費用
403FEATURE_DISABLED帳號中已關閉文件處理功能(四個路徑共通)
404FILE_NOT_FOUND詳細資料、刪除 — 不存在的檔案或其他帳號的檔案
422EXTRACTION_FAILED上傳 — 無法從文件中擷取文字

情緒狀態分析(Emotion)

搭配 Chat API 的摘要週期,分析使用者與 AI 的情緒狀態。不會另外呼叫 LLM,只是在摘要提示詞中加入情緒分析區塊,因此不會額外計費。僅支援 ridm/* 模型。

總覽

啟用條件:

  1. 全域:partner_emotion_enabled ✓
  2. 合作夥伴:在主控台的功能設定中啟用「情緒狀態分析」
  3. 請求:明確指定 emotion: true
  4. 模型:僅支援 ridm/* 系列

摘要週期(summaryEvery)

情緒分析會在每個摘要週期自動執行。可用 summaryEvery 參數調整週期(預設值:5,範圍:1–20)。

請求參數

參數 型別 必填 說明
emotion boolean 啟用情緒狀態分析(僅限 ridm/* 模型,預設值:false)
summaryEvery number 整數 1–20(預設 5)。摘要與情緒的更新週期(以輪為單位)

請求範例

{
  "model": "ridm/gpt-5.6-terra",
  "user": "user_123",
  "messages": [
    { "role": "user", "content": "Today was a rough day..." }
  ],
  "emotion": true,
  "summaryEvery": 3
}

回應欄位

欄位路徑 型別 說明
emotion object|null 情緒狀態(第一個週期之前或 emotion=false 時為 null/省略)
emotion.user object 使用者情緒
emotion.user.type10 string|null 10 類情緒判定(joyful|calm|curious|concerned|excited|thoughtful|neutral|sad|angry|surprised|null)
emotion.user.tone string|null 語氣(自由字串,非固定清單,例如 "warm")或 null
emotion.user.distribution6 object 6 類分布 {joy, sadness, anger, fear, disgust, surprise},總和 = 1000 或 0
emotion.assistant object AI 情緒
emotion.assistant.distribution6 object AI 的 6 類分布
emotion.trend string|null 情緒趨勢(improving|stable|declining|null)
emotion.updatedAt ISO 8601 最後一次更新情緒的時間
emotion.turnsSinceUpdate number 自最後一次更新以來經過的輪數

回應範例

{
  "id": "chatcmpl-xyz",
  "choices": [{
    "message": { "content": "오늘 하루가 힘들었군요..." },
    "finish_reason": "stop"
  }],
  "emotion": {
    "user": {
      "type10": "sad",
      "tone": "warm",
      "distribution6": {"joy": 100, "sadness": 600, "anger": 50, "fear": 100, "disgust": 50, "surprise": 0}
    },
    "assistant": {
      "distribution6": {"joy": 200, "sadness": 100, "anger": 0, "fear": 0, "disgust": 0, "surprise": 0}
    },
    "trend": "stable",
    "updatedAt": "2026-08-26T12:34:56Z",
    "turnsSinceUpdate": 0
  },
  "usage": {...}
}

分布欄位說明(distribution6)

情緒 值 說明
joy 0–1000 喜悅強度
sadness 0–1000 悲傷強度
anger 0–1000 憤怒強度
fear 0–1000 恐懼強度
disgust 0–1000 厭惡強度
surprise 0–1000 驚訝強度

趨勢判定(trend)

串流回應範例(SSE)

在串流模式(stream: true)下,情緒狀態會包含在 event: message_done SSE 事件的資料中。

event: message_done
data: {"finish_reason":"stop","usage":{...},"costWon":2,"recalledMemories":[],"memorySaved":{"id":"turn-1756200000000","keywords":[]},"emotion":{"user":{"type10":"concerned","tone":"warm","distribution6":{...}},"assistant":{...},"trend":"stable","updatedAt":"2026-08-26T12:34:56Z","turnsSinceUpdate":0}}

data: [DONE]

費用說明

注意事項

八字圖片 API

產生呈現八字五行與能量的 AI 藝術圖。以 base64 編碼的 PNG 格式回傳,固定計費 ₩200。

POST /api/v1/partners/v1/image

依據出生年月日產生八字五行圖片。

請求參數

參數 型別 必填 說明
year number O 出生年(例:1990)
month number O 出生月(1-12)
day number O 出生日(1-31)
hour number 出生時(0-23,選填)
minute number 出生分(0-59,選填)
gender string O 性別("male" 或 "female")
style string 風格("background"、"icon"、"portrait",預設值:"background")— 只改變氛圍,尺寸相同

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/image \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{ "year": 1990, "month": 5, "day": 15, "hour": 14, "minute": 30, "gender": "female", "style": "portrait" }'

回應範例

{
  "success": true,
  "data": {
    "imageDataUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
    "costPoints": 200
  }
}

注意事項

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
402INSUFFICIENT_BALANCE餘額少於 1 張圖片的價格
504IMAGE_UPSTREAM_TIMEOUT80 秒內未收到圖片(不計費)

圖片生成 API(模型轉售)

POST /api/v1/partners/v1/images/generations

以與 OpenAI Images API 相同的格式,用一把金鑰呼叫 GPT-Image 與 Nano Banana 模型。每個模型、解析度、品質都有固定的每張價格,表中金額會直接扣除(產生張數 × 每張價格)。提示詞的輸入 token 費用已包含在每張價格中,不會另外加收。

請求參數

參數型別必填說明
modelstringOopenai/gpt-image-2, openai/gpt-image-1-mini, google/nano-banana-pro, google/nano-banana, fal/nano-banana-pro, fal/nano-banana
promptstringO要產生的圖片描述(最多 1,000 字)。超過時回傳 422 PROMPT_TOO_LONG(因為在預留餘額之後才檢查,餘額不足時會先回傳 402),空字串回傳 400 EMPTY_PROMPT
sizestringGPT-Image:1024x1024(預設)、1024x1536(直式)、1536x1024(橫式)、auto(由模型選擇,以該品質中最貴尺寸的價格計費)。舊值 256x256、512x512 會以 1024x1024,1792x1024 以 1536x1024,1024x1792 以 1024x1536 產生並計費。在 Nano Banana 中只當作比例使用,建議改用 aspect_ratio。
qualitystring僅限 GPT-Image:low、medium(預設)、high。舊值 standard=medium、hd=high 仍可照常使用。對 Nano Banana 傳送 low/medium/high 會回傳 400。
aspect_ratiostring僅限 Nano Banana:21:9、16:9、3:2、4:3、5:4、1:1(預設)、4:5、3:4、2:3、9:16。比例不影響價格。優先於 size。
resolutionstring僅限 Nano Banana:Nano Banana 只支援 1K,Nano Banana Pro 支援 1K(預設)、2K、4K。K 只接受大寫。
nnumber產生張數 1~4(預設 1)。Google 直接模型每次呼叫只產生 1 張,也只計費 1 張。

對 GPT-Image 傳送 aspect_ratio、resolution,或請求模型不支援的解析度時,會以 400 INVALID_PARAMETER 拒絕,且不計費。

其他錯誤:MODEL_NOT_FOUND、INVALID_MODEL(400,不存在的模型)、INVALID_PROMPT(400,上游拒絕提示詞)、UPSTREAM_ERROR、RATE_LIMITED(目前為 HTTP 400,本文 status 為 429)、INSUFFICIENT_BALANCE(402)。

每張價格(₩,VAT 另計)

正在載入價目表…

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/images/generations \
  -H "X-Partner-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/nano-banana-pro",
    "prompt": "A serene mountain landscape at sunset",
    "aspect_ratio": "16:9",
    "resolution": "2K"
  }'

回應範例

{
  "created": 1791452814,
  "data": [ { "b64_json": "iVBORw0KGgo..." } ],
  "costWon": 225,
  "requestId": "..."
}

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
400MODEL_NOT_FOUND價目表中沒有的模型
400INVALID_MODELopenai/、google/、fal/ 以外的前綴
400INVALID_PARAMETER模型不接受的選項(對 GPT-Image 傳 aspect_ratio、resolution,對 Nano Banana 傳 quality,不支援的解析度)
400EMPTY_PROMPT提示詞只有空白
400INVALID_PROMPT上游模型拒絕提示詞
400UPSTREAM_ERROR上游錯誤或圖片 0 張(不計費)
HTTP 400,本文 status 429RATE_LIMITED上游速率限制,請稍後再試
402INSUFFICIENT_BALANCE每張價格 × n 大於餘額
422PROMPT_TOO_LONG提示詞超過 1,000 字

錯誤回應與其他 API 相同,為 {"success": false, ...} 格式(只有成功回應不會被包裝)。

耗時較長的產生:非同步回應(202,選用)

高解析度或多張的請求可能超過 1 分鐘。在請求標頭加入 Prefer: respond-async 後,若 60 秒內結果尚未就緒,伺服器不會佔住連線,而是回傳 202 Accepted 與工作 ID,並在伺服器上繼續產生,最長 240 秒。若在 60 秒內完成,會收到與現在相同的 200 回應。不送這個標頭時,行為與現在完全相同(80 秒內未完成時回傳 504 IMAGE_UPSTREAM_TIMEOUT,不計費),請只從能處理 202 的用戶端送出此標頭。

curl -X POST https://api.hrum.ai/api/v1/partners/v1/images/generations \
  -H "X-Partner-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: respond-async" \
  -d '{"model": "google/nano-banana-pro", "prompt": "...", "resolution": "4K"}'

HTTP/1.1 202 Accepted
Location: /api/v1/partners/v1/jobs/imgjob_3f2a...
Retry-After: 5
Preference-Applied: respond-async

{
  "id": "imgjob_3f2a...",
  "object": "image.job",
  "status": "pending",
  "pollUrl": "/api/v1/partners/v1/jobs/imgjob_3f2a...",
  "retryAfter": 5,
  "createdAt": "2026-10-12T03:00:00.000Z",
  "expiresAt": "2026-10-13T03:00:00.000Z"
}

GET /api/v1/partners/v1/jobs/{id}

請使用同一把 API 金鑰(X-Partner-Api-Key),每隔 Retry-After 秒查詢一次。查詢免費,不計入每日請求上限。但每把 API 金鑰每 2 秒最多 1 次,查詢更頻繁時會收到 429 IMAGE_JOB_POLL_RATE_LIMITED 與 Retry-After(秒)。回應為 HTTP 200,狀態以本文的 status 區分。

status本文
pending仍在產生中,請在 Retry-After 標頭、retryAfter 之後再查詢
succeededresult = 同步呼叫原本會回傳的 200 回應(data、costWon、requestId)
failederror = 同步呼叫原本會回傳的錯誤本文(statusCode、code、message),不計費
HTTP代碼發生時機
202—Prefer: respond-async 請求未在 60 秒內完成,請以上述工作 ID 查詢
404IMAGE_JOB_NOT_FOUND不存在、已過期或屬於其他合作夥伴的工作 ID
429IMAGE_JOB_POLL_RATE_LIMITED同一把 API 金鑰在 2 秒內再次查詢,請於 Retry-After 秒後再試
error.statusCode 504IMAGE_UPSTREAM_TIMEOUT240 秒內未收到圖片(不計費)
error.statusCode 413IMAGE_JOB_RESULT_TOO_LARGE結果超過 16MB(不計費)
error.statusCode 503IMAGE_JOB_INTERRUPTED伺服器重新啟動導致工作中斷(不計費),請重新請求
error.statusCode 402—結果產生時餘額不足(不計費)

萬年曆 API

POST /api/v1/partners/v1/manseryeok

包含八字特質(Saju Identity):回應末尾的 identity 欄位會一併提供三災、神煞、空亡、通根、季節強弱、大運/流年時間軸、八字 MBTI(不另外收費,計算失敗時為 null)。

計算命盤(原局)四柱(年、月、日、時)的天干、地支、漢字、五行、十神、藏干、納音、十二長生、神煞。以節氣為基準精確計算,從 命盤分析(用神、扶抑、調候用神、身強弱、清濁、通關、病藥、五行變數)→ 10 步大運(含目前大運、干支合沖刑害)→ 5 年流年(逐年等級、關係、解讀)→ 格局、詳細解讀 → 十干論、季節狀態、空亡、虛字、飛合、暗祿,以頂層基本 30 個欄位 + 選用欄位(含子欄位共 200 個以上)提供完整的八字解讀。出生時間不明時,只有時柱(wonkuk.hour)與需要實際時刻的 trueSolarTime 為 null,用神、格局、身強弱等分析欄位仍會以年、月、日三柱(6 字)為基準計算後照常提供(birthHour.basis: "three_pillars")。

請求參數

參數 型別 必填 說明
year number O 出生年(例:1990)
month number O 出生月(1-12)
day number O 出生日(1-31)
hour number 出生時(0-23)。省略時只會從回應中去掉時柱(wonkuk.hour: null),用神、格局、身強弱、流年等分析欄位會以年、月、日三柱(6 字)為基準計算後提供。未帶 hour 而送出的 minute 會被忽略。
minute number 出生分(0-59,預設值:0)
timezone string O 時區(例:Asia/Seoul)。必填,省略會回傳 400。傳送座標時用來決定標準子午線。以 astrology: true 傳送時,無論有無座標,都會把 natalChart 的出生時刻當作該時區在當時實際使用的時刻(含日光節約時間)來讀取。無法辨識的名稱會以預設時區計算,並在回應中附上警告(UNKNOWN_TIMEZONE)
gender string O 性別("male" 或 "female",必填)
name string 姓名(選填)
astrology boolean 選填 為 true 時,回應會附上 natalChart(太陽、月亮、水星至土星的星座)。上升星座只有在同時傳送出生時刻與出生地點(birthLatitude、birthLongitude 或 country)時才會出現;未帶地點時,星座以正午為基準計算。若需要上升星座推估範圍等詳細資訊,請使用本命盤 API
glossary boolean 選填 為 true 時,會把此命盤中出現的術語(干支漢字、十神、十二長生、納音、神煞、藏干、沖刑、地支關係、格局、空亡、三災)的說明(title、short、body,lang 語言)附在回應的 glossary 中。不另外收費。沒有請求語言說明的術語會以韓文回傳,並在該項目附上 "fallbackLanguage": "ko"。glossary 的鍵與 lang 無關,一律為韓文/漢字代碼
lang string 解讀字串的語言:ko(預設,不翻譯)、en、ja、th。使用與 INTA 應用程式萬年曆畫面相同的翻譯表
calendar · isLeapMonth string · boolean 為 "lunar" 時,會把 year、month、day 當作農曆,轉換成國曆後計算(預設 "solar")。isLeapMonth: true 代表閏月,若該年沒有該閏月,會回傳 400 INVALID_LUNAR_DATE(2026-10-12 起,不計費)。農曆以韓國天文研究院(KASI)為準,接受農曆 1900-01-01 ~ 2050-11-30 的範圍
birthLatitude · birthLongitude number 出生地座標(兩者都要傳送)。以經度做真太陽時校正。標準子午線依 timezone 的標準時間(不含日光節約時間)決定。natalChart(星座)不是依標準時間,而是依出生時實際使用的時刻(含日光節約時間)繪製
country string 出生國家的 2 字母代碼。未帶座標而傳送 KR、JP、TH 時,以該國代表經度校正(其他國家不校正)
zaSiRule string 子時(23 點以後)的日柱:"traditional"(預設,取隔天日柱)、"yajaSi"(夜子時,取當天日柱;地點校正後 23 點時段的時柱天干以隔天日干為準,2026-10-20 起)
birthTimePrecision string exact、approximate、estimated、unknown。地點校正只在 exact 時套用。省略時若傳送了座標或 country,視為 exact。韓國日光節約時間(1948~51、1955~60、1987~88)期間的出生時刻,無論此值與地點為何,都會減去 1 小時以標準時間讀取(2026-10-16,與 INTA 應用程式相同)。country 不是 KR 或 timezone 不是首爾時,不會扣除韓國日光節約時間

回應欄位(基本 30 個 + 選用欄位)

欄位 型別 說明
wonkuk object 命盤(四柱)。year、month、day、hour(出生時間不明時 hour 為 null)。各項目請參閱PillarFull 結構
trueSolarTime object|null 真太陽時(經度)校正結果。只有在傳送座標(birthLatitude、birthLongitude)或 country(KR、JP、TH)且 birthTimePrecision 為 exact 時(傳送地點時預設為 exact)才有值,其他情況為 null。欄位:original、corrected(ISO 8601)、originalLocal、correctedLocal(HH:MM)、longitudeCorrection、equationOfTime、totalCorrectionMinutes(分鐘)、dayShift、dstApplied、basis('coords' 或 'country')。出生時間不明時為 null
ohaengBalance object 五行平衡。{ 목: int, 화: int, 토: int, 금: int, 수: int }(木、火、土、金、水)
yongshin string 最終用神:依 5 法(專旺、調候、扶抑、通關、病藥)判定的結果,2026-10-08 起與 yongshinDetail.primary 為相同值(例:"수" = 水)
johuYongshin string|null 調候用神(與「扶抑用神」區分)
eokbuYongshin string 扶抑用神(權衡身強、身弱後決定的用神)。可能與最終用神(yongshin)不同
yongshinDetail object 完整版用神引擎的結果。依 5 法優先順序(專旺 → 調候 → 扶抑 → 通關 → 病藥)判定, 包含 method(採用的方法)、primary(用神)、secondary(輔助用神)、 reasoning(判定依據的句子陣列)、shin(用神、喜神、忌神、仇神、閒神 5 個等級)、 favorable_sipsin/unfavorable_sipsin(吉、凶十神)、 element_states(各五行的數量、過與不足、吉凶)。 上方的 yongshin 與此引擎的 primary 為相同值(2026-10-08 起)。 需要連同判定依據一起解讀時,請使用此欄位。 出生時間不明時,也會以年、月、日三柱(6 字)為基準計算後提供。
ilganSummary string 日干十干論。例:"壬水 — 큰 바다의 기운. 지혜롭고 포용력이 넓어요."(只使用日干,因此無論出生時間是否不明都會提供)
daeun array 10 步大運(固定 10 個)。各項目包含起始年齡、天干、地支、五行、十神、神煞、isCurrent(是否為目前大運)。區間為 startAge 以上、未滿 endAge,因此前一區間的 endAge 與下一區間的 startAge 相同。沒有 gender 或為 "other" 時為空陣列。請參閱DaeunPeriod 結構
seun array 5 年流年:以今年為中心前後各 2 年(今年 −2 年 ~ +2 年,年份遞增),只有今年的項目為 isCurrent: true。各項目包含年份、天干、地支、五行、grade(good/caution/excellent/neutral)、關係(害/六合/刑等)、摘要。請參閱SeunYear 結構
branchRelations array 地支關係。年月日時中有沖、刑、合的地支組合清單。各項目包含 type('沖(충)'/'刑(형)'/'半合(반합)' 等)、pillars、description(例:"丑未沖 (축미충)")
gongmang array 空亡地支 2 個:以日柱為準的旬中空亡(不論命盤中有無該地支,固定 2 個)。例:["술", "해"]
cheonEulGwiIn array 命盤地支中屬於天乙貴人的地支清單。與各柱 minorSinsal 中帶有 "천을귀인" 的柱之地支採相同標準。沒有符合的柱時為 []。例:["묘"]
wolryeong string 月令(依交節而定的當月令支)。例:"축"
daeunNumber number 大運數:第一步大運開始的年齡(daeun[0].startAge,例:3)。不是目前大運的順序,目前大運請以 daeun[].isCurrent 尋找
daeunDirection string 大運方向。"순행"(順行)或 "역행"(逆行)
gyeokguk object|null 格局判定。name('정관격' 等)、summary('질서·명예·합리')。出生時間不明時,也會以年、月、日三柱(6 字)為基準計算
gyeokgukDetail object|null 格局詳細解讀。primary、source、trigger、interpretation(core/career/personality/challenge)。出生時間不明時,也會以年、月、日三柱(6 字)為基準計算
cheonganDetail object|null 十干論詳細。ilgan、hanja、archetype、characteristics、seasonal、relations。出生時間不明時,也會以年、月、日三柱(6 字)為基準計算
hapChungReport object|null 天干、地支刑沖會合綜合報告。命盤內合/沖是否維持,以及大運/流年中新形成的關係。出生時間不明時,也會以年、月、日三柱(6 字)為基準計算
heojaReport object|null 虛字綜合報告。hapHeo、jaHeo、bihap、bihapEmergence、heojaGyeok、amrok。出生時間不明時,也會以年、月、日三柱(6 字)為基準計算。但 heojaGyeok(虛字格)需要實際的時支才能成立,因此為空
gongmangDetail object|null 空亡詳細報告。以年柱、日柱為準的空亡、五行是否落空亡等
ohaengByeonsuHits array 自動擷取五行變數。套用旺、剋、順化公式的範例。各項目包含 key、subject(五行)、target、formula_idiom、description、category
strength object|null 身強弱分數與等級。dayMaster、score(-100~+100)、result('신강' 身強/'신약' 身弱)、level、breakdown(季節、扶助、剋洩、藏干、通根)。出生時間不明時,也會以年、月、日三柱(6 字)為基準計算
jeongtak object|null 清濁判定。verdict('정' 清/'탁' 濁)、reasons、severity。出生時間不明時,也會以年、月、日三柱(6 字)為基準計算
tonggwan object|null 是否通關。複合邏輯的結果
byeongyak object|null 是否病藥。複合邏輯的結果
natalChart object|null 西洋占星本命盤(選用,僅在 astrology=true 時)。太陽、月亮、水星至土星 7 個天體的星座,以及上升星座(有傳送地點時)
countryCodeUsed string|null 計算此回應時使用的國家代碼(有傳送 country 時),沒有則為 null
identity object|null 一律包含(2026-10-10 起)。八字特質:rooting_hints(通根)、season_strength_hint(季節強弱)、sinsal_list(神煞)、gongmang(空亡)、samjae(三災)、timeline(大運/流年時間軸)、mbti_inference(八字 MBTI)、coherence。計算失敗時為 null。請參閱八字特質
ohaengDeficient array of string 一律包含(2026-10-10 起)。ohaengBalance 中數量為 0 的五行清單(沒有則為 [])。lang 不是 ko 時會以翻譯後的名稱回傳(ohaengBalance 的鍵維持韓文)
glossary object 選用,僅在 glossary=true 時。術語鍵 → { title, short, body, fallbackLanguage? }
lunarInput object 選用,僅在 calendar: "lunar" 時。農曆 → 國曆的轉換明細
birthHour object 選用,僅在省略 hour 時。出生時間不明的中繼資料(請參閱下方注意事項)

PillarFull 結構(各柱的子欄位)

回應中 wonkuk.year、wonkuk.month、wonkuk.day、wonkuk.hour 各自具有的欄位:

欄位 型別 說明
stem string 天干。"갑", "을", "병", "정", "무", "기", "경", "신", "임", "계"
branch string 地支。"자", "축", "인", "묘", "진", "사", "오", "미", "신", "유", "술", "해"
stemHanja string 天干漢字。"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"
branchHanja string 地支漢字。"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"
ohaeng string 五行。"목", "화", "토", "금", "수" 其中之一(木、火、土、金、水)
stemSipsin string 天干十神(相對於日干)。"정관", "편관", "정재", "편재", "식신", "상관", "정인", "편인", "비견", "겁재" 其中之一
branchSipsin string 地支十神(相對於日干)。與天干十神相同的 10 種
jijanggan array of string 藏干(地支中隱藏的天干)。例:["갑", "을", "목"] 或 ["갑", "을"] 等
chunghyung array of string 沖刑(與其他柱的關係)。"沖(충)"、"刑(형)" 等。例:["沖(충)", "刑(형)"]
hapPosition array of string 合的位置(與其他柱的關係)。"半合(반합)"、"육합" 等。例:["半合(반합)"]
ungSung string 十二長生。"장생", "목욕", "관대", "건록", "제왕", "쇠", "병", "사", "묘", "절", "태", "양" 其中之一
ungSungSub string(選填) 十二長生輔助資訊(選用欄位)
napEum string 納音五行。例:"성두토"、"간하수"、"검봉금" 等
majorSinsal array of string 主要神煞。例:["장성살"]、["지살"] 等
minorSinsal array of string 輔助神煞。例:["천을귀인", "귀문관살", "원진살", "현침살", "육해살"] 等

DaeunPeriod 結構(各步大運)

欄位 型別 說明
startAge number 起始年齡(從此年齡開始此區間)
endAge number 結束年齡:不包含此年齡,與下一區間的 startAge 相同(例:3~13、13~23)
stem string 天干
branch string 地支
stemHanja string 天干漢字
branchHanja string 地支漢字
ohaeng string 五行
isCurrent boolean 是否為目前大運(true 表示目前進行中)
stemSipsin string 天干十神
branchSipsin string 地支十神
sinsal array of string 神煞陣列

SeunYear 結構(流年各年)

欄位 型別 說明
year number 西元年份
stem string 天干
branch string 地支
stemHanja string 天干漢字
branchHanja string 地支漢字
ohaeng string 五行
isCurrent boolean 是否為今年流年
grade string 等級。"good"(順遂)、"excellent"(非常好)、"caution"(留意)、"neutral"(無變化)
relations array 干支關係。各項目包含 type(害/六合/刑等)、target(年柱/月柱等)、description
summary string 年度解讀摘要。例:"전체적으로 순조로운 흐름이 예상돼요."
sinsal array of string 神煞陣列

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/manseryeok \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "year": 2000, "month": 1, "day": 15, "hour": 14, "minute": 30,
    "gender": "male", "calendar": "solar", "timezone": "Asia/Seoul"
  }'

回應範例(節錄:2000-01-15 14:30 男性)

{
  "success": true,
  "data": {
    "wonkuk": {
      "year": {
        "stem": "기", "branch": "묘", "stemHanja": "己", "branchHanja": "卯",
        "ohaeng": "토", "stemSipsin": "정관", "branchSipsin": "상관",
        "jijanggan": ["갑", "을"], "chunghyung": [], "hapPosition": ["半合(반합)"],
        "ungSung": "사", "napEum": "성두토",
        "majorSinsal": ["장성살"],
        "minorSinsal": ["천을귀인", "귀문관살", "원진살", "현침살", "육해살"]
      },
      "month": { ... },
      "day": { ... },
      "hour": { ... }
    },
    "trueSolarTime": null,
    "ohaengBalance": { "목": 1, "화": 2, "토": 3, "금": 1, "수": 1 },
    "yongshin": "수",
    "johuYongshin": "화",
    "yongshinDetail": {
      "method": "억부",
      "primary": "수",
      "secondary": ["금"],
      "reasoning": ["일간 임(수) 신약", "신약 + root 있음(8) → 비겁(수)"],
      "shin": { "yongshin": "수", "huishin": "금", "gishin": "토", "gushin": "화", "hanshin": "목" },
      "favorable_sipsin": ["편인", "정인", "비견", "겁재"],
      "unfavorable_sipsin": ["편관", "정관", "편재", "정재", "식신", "상관"],
      "element_states": { "목": { "count": 1, "state": "lack", "effect": "neutral" }, "...": "5오행" }
    },
    "eokbuYongshin": "수",
    "ilganSummary": "壬水 — 큰 바다의 기운. 지혜롭고 포용력이 넓어요.",
    "daeun": [
      {
        "startAge": 3, "endAge": 13,
        "stem": "병", "branch": "자", "stemHanja": "丙", "branchHanja": "子",
        "ohaeng": "화", "isCurrent": false,
        "stemSipsin": "편재", "branchSipsin": "겁재",
        "sinsal": ["년살", "장성살"]
      },
      {
        "startAge": 13, "endAge": 23,
        "stem": "을", "branch": "해", "stemHanja": "乙", "branchHanja": "亥",
        "ohaeng": "목", "isCurrent": false,
        "stemSipsin": "상관", "branchSipsin": "비견",
        "sinsal": ["지살", "망신살"]
      },
      {
        "startAge": 23, "endAge": 33,
        "stem": "갑", "branch": "술", "stemHanja": "甲", "branchHanja": "戌",
        "ohaeng": "목", "isCurrent": true,
        "stemSipsin": "식신", "branchSipsin": "편관",
        "sinsal": ["천살", "월살"]
      }
      // … cycles 4–10 (startAge 33–93) omitted — the actual response has 10
    ],
    "seun": [
      // 2024 and 2025 entries omitted
      {
        "year": 2026, "stem": "병", "branch": "오", "stemHanja": "丙", "branchHanja": "午",
        "ohaeng": "화", "isCurrent": true, "grade": "good",
        "relations": [
          { "type": "해", "target": "월주", "description": "오-축 해" },
          { "type": "육합", "target": "시주", "description": "오-미 육합" }
        ],
        "summary": "전체적으로 순조로운 흐름이 예상돼요. (해, 육합 작용)",
        "sinsal": ["육해살", "재살"]
      }
      // 2027 and 2028 entries omitted — the actual response has 5: two years either side of this year
    ],
    "branchRelations": [
      { "type": "沖(충)", "pillars": ["축", "미"], "description": "丑未沖 (축미충)" },
      { "type": "半合(반합)", "pillars": ["묘", "미"], "description": "卯未合 (묘미합)" }
    ],
    "gongmang": ["술", "해"],
    "cheonEulGwiIn": ["묘"],
    "wolryeong": "축",
    "daeunNumber": 3,
    "daeunDirection": "역행",
    "gyeokguk": {
      "name": "정관격",
      "summary": "질서·명예·합리"
    },
    "gyeokgukDetail": { ... },
    "cheonganDetail": { ... },
    "hapChungReport": { ... },
    "heojaReport": { ... },
    "gongmangDetail": { ... },
    "ohaengByeonsuHits": [
      {
        "key": "to_wang_deuk_mok",
        "subject": "土", "target": "木",
        "formula_idiom": "방능소통(方能疏通)",
        "description": "토가 왕성한데 목을 얻으면 소통이 된다",
        "category": "wang_geuk_sunwha"
      },
      {
        "key": "gang_to_deuk_geum",
        "subject": "土", "target": "金",
        "formula_idiom": "방제기해(方制其害)",
        "description": "강한 토가 금을 얻으면 그 피해를 막는다",
        "category": "gang_seolgi_sunwha"
      }
    ],
    "strength": {
      "dayMaster": "임",
      "score": -66,
      "result": "신약",
      "level": "중약",
      "breakdown": { "season": -30, "support": 8, "control": -38, "hidden": -9, "root": 8 },
      "root": { "rooted": true, "rootScore": 8 }
    },
    "jeongtak": {
      "verdict": "탁",
      "reasons": ["파괴 십신 2개 감지", "용신 금 생 ✓", "일주 신약"],
      "severity": "극탁"
    },
    "tonggwan": { ... },
    "byeongyak": { ... },
    "countryCodeUsed": null,
    "identity": {
      "rooting_hints": { ... }, "season_strength_hint": { ... }, "sinsal_list": [ ... ],
      "gongmang": { ... }, "samjae": { ... }, "timeline": { ... },
      "mbti_inference": { ... }, "coherence": { ... }
    },
    "ohaengDeficient": []
  }
}

此範例是在 2026 年呼叫的結果,因此 daeun[].isCurrent、seun 的年份會依呼叫年份而不同。{ ... } 與 // 行代表省略。此範例是未傳送地點的請求,因此 trueSolarTime 為 null。在同一請求加上 "country": "KR"(或座標)後,trueSolarTime 會帶入校正結果("basis": "country"),countryCodeUsed 會變成 "KR"。校正結果的格式請參閱下方注意事項中的農曆輸入範例。

注意事項

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
400INVALID_LUNAR_DATE · INVALID_LOCATION不存在的農曆日期/只傳送緯度、經度其中之一(不計費)
402(無)餘額少於呼叫價格:此 API 呼叫前不檢查餘額,因此會收到沒有代碼的 402

終身八字 API

POST /api/v1/partners/v1/lifetime

依出生年月日時計算命盤,並把對應此命盤的組件(日柱、日干×月支、日干×身強弱、日干×用神、五行過多/不足最多 3 個、最強的十神群組)的解讀段落,整理成性格、財運、事業、感情、健康、人際關係、建議 7 個主題回傳。段落依 HRUM 八字理論撰寫,相同輸入一律得到相同結果。命盤判定與萬年曆 API 相同。

全部 7 個主題
單一主題(topic)
星座、紫微斗數層(layers)

請求參數

參數型別必填說明
year · month · daynumberO出生年(1900-2100)、月、日(預設國曆,calendar: "lunar" 時為農曆)
hour · minutenumber出生時刻。省略 hour 時,以與萬年曆 API 相同的出生時間不明規則(年、月、日三柱基準)計算
timezonestringO時區(例:Asia/Seoul)。無法辨識的名稱會以預設時區計算,並在回應中附上警告(UNKNOWN_TIMEZONE)
genderstringO"male" 或 "female"
topicstring只取得一個主題時:personality、wealth、career、love、health、relationships、advice。省略時為全部 7 個主題
langstringko(預設)、en、ja、th
layersstring[]附加解讀層:"astro"(星座:太陽、月亮、上升星座)、"ziwei"(紫微斗數:命宮主星 + 各主題宮位主星)。依星座 → 紫微斗數的順序接在各主題的八字段落之後。省略或為 [] 時,回應與現在完全相同
calendar · isLeapMonthstring · boolean為 "lunar" 時,會把 year、month、day 當作農曆,轉換成國曆後計算(預設 "solar")。isLeapMonth: true 代表閏月,若該年沒有該閏月,會回傳 400 INVALID_LUNAR_DATE(2026-10-12 起)。以農曆傳送時,回應會附上 lunarInput(與萬年曆 API 相同格式)
birthLatitude · birthLongitudenumber出生地座標(兩者一起傳送)。八字段落與 layers 以相同基準做真太陽時校正。標準子午線依 timezone 的標準時間(不含日光節約時間)決定。上升星座需要同時有出生時刻與座標才會出現
countrystring出生國家的 2 字母代碼。未帶座標而傳送 KR、JP、TH 時,以該國代表經度校正(其他國家不校正)。layers 也使用此國家(省略時依 lang 推估)
zaSiRulestring子時(23 點以後)的日柱:"traditional"(預設,取隔天日柱)、"yajaSi"(夜子時,取當天日柱;地點校正後 23 點時段的時柱天干以隔天日干為準,2026-10-20 起)。只用於八字段落(紫微斗數固定自 23 點起算隔天)
birthTimePrecisionstringexact、approximate、estimated、unknown。地點校正只在 exact 時套用。省略時若傳送了座標或 country,視為 exact

請求範例

{
  "year": 1990, "month": 9, "day": 4, "hour": 14, "minute": 30,
  "timezone": "Asia/Seoul", "gender": "male",
  "topic": "career", "lang": "ko"
}

回應範例

{
  "success": true,
  "data": {
    "topics": [
      {
        "topic": "career",
        "paragraphs": [
          { "component": "ilju", "key": "임신", "text": "..." },
          { "component": "ilgan_wolji", "key": "임_신", "text": "..." },
          { "component": "ilgan_strength", "key": "임_신강", "text": "..." },
          { "component": "ilgan_yongshin", "key": "임_화", "text": "..." },
          { "component": "ohaeng_state", "key": "목_lack", "text": "..." },
          { "component": "ohaeng_state", "key": "토_lack", "text": "..." },
          { "component": "ohaeng_state", "key": "수_lack", "text": "..." },
          { "component": "top_sipsin", "key": "인성", "text": "..." }
        ]
      }
    ],
    "lang": "ko",
    "fallbackLanguage": null,
    "engine": { "version": 1, "styleVersion": "v1" }
  }
}
  • topics 一律依上述 7 個主題的順序,主題內的段落依組件順序排列(日柱 → 日干×月支 → 身強弱 → 用神 → 五行狀態 → 十神群組)。
  • key 是韓文判定值(與語言無關)。ohaeng_state 依命盤不同為 0~3 個。
  • 語言:若尚未有請求語言的段落,只有該段落會以韓文回傳,並標示 fallbackLanguage: "ko"。
  • 時刻校正:未傳送座標或 country 時,直接以輸入時刻計算(與萬年曆 API 相同)。若需要與 INTA 應用程式(韓文,直接輸入時刻)相同的段落,請傳送 country: "KR"。海外出生者只靠 timezone 不會校正,請一併傳送座標。
  • 2026-10-11 變更:傳送座標時,八字段落也會做真太陽時校正(先前只用於 layers)。這是為了讓同一回應內的八字、星座、紫微斗數使用相同的時刻基準,因此原本有傳送座標的呼叫,八字段落可能會改變。未傳送新欄位與座標的呼叫,回應維持不變。

星座、紫微斗數層(layers)

與 INTA 應用程式的終身八字構成相同。每個主題各加上一段星座(太陽、月亮、上升星座)段落與紫微斗數命宮(命宮)主星組合段落,接著附上負責該主題之宮位的主星段落:財運(wealth)= 財帛宮(財帛)、事業(career)= 官祿宮(官祿)、感情(love)= 夫妻宮(夫妻)、健康(health)= 疾厄宮(疾厄)。性格、人際關係、建議主題只附命宮段落。各層的第一段會附上 label(例:"별자리로 보면"),可在畫面上當作小標題使用。指定 topic 時,各層也只附上該主題的段落。

{
  "year": 1990, "month": 9, "day": 4, "hour": 14, "minute": 30,
  "timezone": "Asia/Seoul", "gender": "male",
  "birthLatitude": 37.5665, "birthLongitude": 126.978,
  "topic": "career", "lang": "ko",
  "layers": ["astro", "ziwei"]
}
{
  "success": true,
  "data": {
    "topics": [
      {
        "topic": "career",
        "paragraphs": [
          { "component": "ilju", "key": "임신", "text": "..." },
          ...
          { "component": "top_sipsin", "key": "인성", "text": "..." },
          { "component": "astro_sun", "key": "vir", "text": "...", "label": "별자리로 보면" },
          { "component": "astro_moon", "key": "pis", "text": "..." },
          { "component": "astro_asc", "key": "sag", "text": "..." },
          { "component": "ziwei_ming", "key": "tt_jm", "text": "...", "label": "자미두수로 보면" },
          { "component": "ziwei_palace", "key": "cr_tj", "text": "..." }
        ]
      }
    ],
    "lang": "ko",
    "fallbackLanguage": null,
    "engine": { "version": 1, "styleVersion": "v1" },
    "missingSections": 0,
    "layers": {
      "astro": { "included": true, "costWon": 20, "note": null },
      "ziwei": { "included": true, "costWon": 20, "note": null }
    }
  }
}
  • key:星座為英文三字母縮寫(vir=處女座等),紫微斗數為命宮主星縮寫組合(tt_jm=天同、巨門,沒有主星時為 empty)。
  • ziwei_palace:各主題的宮位段落。key 為 palace abbreviation_main-star abbreviation(宮位縮寫_主星縮寫)(wl=財帛、cr=官祿、sp=夫妻、hl=疾厄,例:cr_tj=官祿宮 天機);宮位有兩顆主星時段落也有兩段,沒有主星的宮位(空宮)則不附。緊接在命宮段落之後,沒有 label(只有在該主題沒有命宮段落時,第一個宮位段落才會附上 label)。價格維持紫微斗數層 +₩20。
  • 沒有出生時刻時:紫微斗數層會被省略,layers.ziwei 會回傳 "included": false、"reason": "birth_time_required" 與說明文字(note)。星座只會以正午為基準附上太陽(若月亮星座確定,也附上月亮)。
  • 沒有座標時:上升星座段落會被省略,原因寫在 layers.astro.note。未傳送 country 時,各層的出生國家依 lang 推估(ko→韓國、ja→日本、th→泰國)。
  • reason 為 birth_time_required、chart_unavailable、narrative_unavailable 其中之一,被省略的層不計費。
  • missingSections:應該包含但因尚無解讀文句而被省略的段落數(基本主題 + 附加的層)。為 0 表示沒有缺少的段落。即使部分缺少,價格也相同。

價格

  • 全部(7 個主題)₩100/次,指定 topic ₩20/次。只有成功的呼叫才計費,相同輸入的重複呼叫也會各自計費(冪等性)。
  • layers:每個實際附上段落的層 +₩20(全部或單一主題皆同)。例:全部 + 星座 + 紫微斗數 = ₩140。餘額會事先以包含所請求層的金額確認。
  • 輸入錯誤(400)、餘額不足(402)、段落讀取失敗(503 lifetime_narrative_unavailable)不計費。使用量紀錄的 endpoint 為 lifetime。
  • 輸入選項:出生資料輸入與萬年曆 API 相同(calendar、isLeapMonth、座標、country、zaSiRule、birthTimePrecision)。不接受萬年曆專用選項(astrology、glossary、name),傳送時回傳 400(不計費)。
  • 帳號未開通此功能時,回傳 404 lifetime_not_enabled(不計費)。

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
404lifetime_not_enabled帳號未開通此功能
400INVALID_LUNAR_DATE · INVALID_LOCATION不存在的農曆日期/只傳送緯度、經度其中之一
402INSUFFICIENT_BALANCE以包含所請求層的金額事先確認時餘額不足
503lifetime_narrative_unavailable無法讀取解讀段落(不計費)

紫微斗數命盤 API

POST /api/v1/partners/v1/ziwei-chart

依出生年月日時計算紫微斗數(紫微斗數)命盤。回傳 12 宮(宮名、天干、地支、大限年齡)、14 主星與輔佐星(含亮度、生年四化)、五行局、命宮、身宮位置、生年四化,以及基準日的大限、流年。相同輸入一律得到相同結果。標籤會以請求的語言填入,key 是與語言無關的固定英文值。

計算設定(固定)

  • 閏月:閏月 15 日以前視為該月,16 日起視為下個月。
  • 23 點時段出生:以隔天子時計算(notes.lateZiNotice 中有說明文字)。
  • 年的分界:農曆正月初一(春節)。在立春至春節之間出生時,八字(以立春為準)與年干支可能不同,此時 chart.yearBasisNote 會附上說明文字。
  • 時刻校正:與八字規則相同。預設直接以輸入時刻計算(與萬年曆 API 相同),若與 birthTimePrecision: "exact" 一起傳送座標(birthLatitude、birthLongitude)或 countryCode(KR、JP、TH),就會做真太陽時校正。校正結果會出現在 clock。
  • 四化:三合派安星法 + 生年四化。引擎固定為 iztro 2.6.1(chart.engine)。

請求參數

參數型別必填說明
year · month · daynumberO出生年(1900-2100)、月、日
hournumberO出生時(0-23)。紫微斗數沒有出生時刻就無法排出命盤,省略時回傳 400 birth_time_required
minutenumber出生分(0-59),省略時為 0
genderstringO"male" 或 "female"(決定大限的行進方向)
calendarstringsolar(預設)或 lunar
isLeapMonthboolean農曆閏月時為 true。國曆輸入時忽略。若該年沒有該閏月,會以平月計算,chart.lunarDate.isLeapMonth 回傳 false
birthTimePrecisionstringexact(真太陽時校正)或 approximate(不校正 + notes.approximateTimeNote)。省略時不校正
birthLatitude · birthLongitudenumber出生地座標(用於 exact 校正)
countryCodestring出生國家 ISO 2 碼,僅限大寫(例:KR,kr 會回傳 400)。沒有座標時以代表經度校正
birthTimezoneOffsetnumber出生時刻的 UTC 偏移(分鐘,540 = KST)
referenceDatestring大限、流年基準日 YYYY-MM-DD(預設:今天,韓國時間)
langstringko(預設)、en、ja、th
timezonestring為了與萬年曆 API 相容(不用於計算,因此即使是無法辨識的名稱也不會附上警告)
readingsboolean為 true 時,回應會附上 readings(命宮主星組合、7 個主題、財帛/官祿/夫妻/疾厄宮主星的解讀段落,lang 語言)。另加 ₩20(合計 ₩70)。省略時回應不變

請求範例

{
  "year": 1990, "month": 5, "day": 15, "hour": 14, "minute": 30,
  "gender": "female", "referenceDate": "2026-10-08", "lang": "ko"
}

回應範例(部分)

{
  "success": true,
  "data": {
    "engineVersion": 1,
    "lang": "ko",
    "referenceDate": "2026-10-08",
    "clock": {
      "inputSolarDate": "1990-05-15", "inputTime": "14:30",
      "correctedSolarDate": "1990-05-15", "correctedTime": "14:30",
      "correctionMinutes": 0, "dstApplied": false, "basis": null,
      "hourBranch": { "key": "wei", "label": "미" }
    },
    "chart": {
      "engine": { "name": "iztro", "version": "2.6.1", "config": { ... } },
      "solarDate": "1990-05-15",
      "lunarDate": { "year": 1990, "month": 4, "day": 21, "isLeapMonth": false },
      "yearGanzhi": "경오",
      "yearBasisNote": null,
      "fiveElementsClass": { "key": "earth5", "label": "토오국" },
      "soulPalaceBranch": { "key": "xu", "label": "술" },
      "bodyPalaceBranch": { "key": "zi", "label": "자" },
      "palaces": [
        ...,
        {
          "key": "ming", "label": "명궁",
          "branch": { "key": "xu", "label": "술" },
          "stem": { "key": "bing", "label": "병" },
          "isBodyPalace": false,
          "majorStars": [
            { "key": "ziwei", "label": "자미", "brightness": { "key": "de", "label": "득" }, "mutagen": null },
            { "key": "tianxiang", "label": "천상", "brightness": { "key": "de", "label": "득" }, "mutagen": null }
          ],
          "minorStars": [
            { "key": "lingxing", "label": "영성", "brightness": { "key": "miao", "label": "묘" }, "mutagen": null }
          ],
          "decadal": { "from": 5, "to": 14, "isCurrent": false }
        },
        ...
      ],
      "mutagens": [
        { "type": "lu", "label": "화록", "starKey": "taiyang", "starLabel": "태양", "palaceKey": "children", "palaceLabel": "자녀궁" },
        { "type": "quan", "label": "화권", "starKey": "wuqu", "starLabel": "무곡", "palaceKey": "wealth", "palaceLabel": "재백궁" },
        { "type": "ke", "label": "화과", "starKey": "taiyin", "starLabel": "태음", "palaceKey": "children", "palaceLabel": "자녀궁" },
        { "type": "ji", "label": "화기", "starKey": "tiantong", "starLabel": "천동", "palaceKey": "health", "palaceLabel": "질액궁" }
      ],
      "currentDecadal": { "palaceKey": "children", "from": 35, "to": 44 },
      "yearly": { "palaceKey": "wealth", "year": 2026 }
    },
    "features": [
      "bright:紫微=得", "co:紫微+天相@命", "cs:命=胎", "dir:逆", "hua:祿=太陽@子女",
      "lhua:忌=廉貞@流年", "limit:大限@子女", "limit:小限@辰", "ming:戌", "mingzhu:祿存",
      "star:天姚@辰", "star:紫微@命", "year:庚", "yy:陽女", ...
    ],
    "notes": { "lateZiNotice": null, "approximateTimeNote": null }
  }
}

以 "lang": "ja" 傳送相同請求時,只有標籤會改變,例如:"yearGanzhi": "庚午"、命宮 "label": "命宮"、主星 "紫微"、"天相"、五行局 "土五局"、四化 "化禄"。

  • palaces 一律為 12 個,依地支順序 寅 → 丑(寅卯辰巳午未申酉戌亥子丑)排列。宮位種類請以 key(ming、siblings、spouse、children、wealth、health、travel、friends、career、property、fortune、parents)區分。
  • mutagens 是生年四化(化祿、化權、化科、化忌)以及該星所坐的宮位。星物件的 mutagen 也是生年四化。
  • features 是以紫微斗數規則鍵(<kind>:<body>,使用古典漢字 token)記錄此命盤中成立之事實的排序字串陣列(每張命盤約 1,200 個,約 27KB)。內容包含星曜位置、亮度、生年四化、同宮、對宮、三方四正、夾、宮干、五行局、命宮/身宮、納音、陰陽、大限方向、運限宮位及其中的星曜,以及命盤上不會另外出現的雜曜位置、長生十二神、小限、大限/流年四化、命主、身主、來因宮,因此可以用字串比對來核對規則條件。因大小考量只省略兩類:三顆星的 co、meet(co:A+B+C = co:A+B 且 co:A+C,meet 亦同),以及涉及雜曜的關係鍵(以 star:<minor star>@<branch> 與 pal:、shen:、limit: 計算對宮 +6、三方四正 0、±4、+6、夾 ±1 即可)。
  • 規則依據卡片的原文引用:紫微斗數規則卡片(解讀資料庫,僅限獲准的合作夥伴)的 sources 中,未能在公開原文(公有領域版本)中確認的引用(match: "PARTIAL" 且沒有原文位置 foundAt 者),會去掉原文(quote)與位置(location),並以 "citation": "pending"(出處確認中)回傳。規則文句與 sourceId 維持不變,在原文中確認的引用(match: "EXACT")、已確認原文位置(foundAt)的 PARTIAL 引用以及引擎依據都不會改變。這是為了避免讓未確認出處的引用看起來像已確認的出處。
  • 傳本引用(match: "QUOTED"):沒有公有領域錨點的傳本引用。原文(quote)與位置(location)照常回傳。有校訂、校勘痕跡的引用不屬於此類。
  • 在第一步大限起始年齡之前,currentDecadal 為 null。yearly.year 是流年所依據的農曆年(春節之前則為前一年)。
  • readings: true 時,readings = { ming, topics[], palaces[], lang, costWon, missingSections, version }。ming 是命宮主星組合段落(key、text、lang),topics 是各主題段落(topic、text、lang),palaces 是各宮位、主星段落(palace、star、text、lang)。沒有請求語言文句的段落會以韓文回傳,該段落的 lang 為 ko。missingSections 是因尚無解讀文句而被省略的段落數(為 0 表示齊全)。即使部分缺少,追加價格也相同。version 標示讀取段落所用解讀辭典的版本(例:nr-3f9a0c1d2e4b)。值相同代表文句相同,辭典文句修訂後值就會改變。請只用來比較,不要解析其格式。

沒有出生時刻時(400)

{
  "success": false,
  "statusCode": 400,
  "code": "birth_time_required",
  "message": "Zi Wei Dou Shu needs the birth hour (hour 0-23). ...",
  "partial": {
    "birthYearMutagens": [
      { "type": "lu", "label": "화록", "starKey": "taiyang", "starLabel": "태양" },
      ...
    ],
    "yearStemStars": [
      { "key": "lucun", "label": "녹존", "branch": { "key": "shen", "label": "신" } },
      ...
    ]
  }
}

只會在 partial 中回傳不需時刻也能確定的生年四化星,以及由年干決定的星(祿存、擎羊、陀羅、天魁、天鉞)的地支。宮位配置需要時刻才能確定,請勿自行編造。此回應不計費。

價格

  • ₩50/次。readings: true 時 +₩20(合計 ₩70)。只有成功的呼叫才計費,相同輸入的重複呼叫也會各自計費(冪等性)。
  • 輸入錯誤(400 invalid_birth_date、birth_time_required 等)與餘額不足(402)不計費。使用量紀錄的 endpoint 為 ziwei_chart。
  • 其他不計費的錯誤:404 ziwei_not_enabled(帳號未開通此功能)、404 ziwei_readings_not_enabled(未開通解讀段落)、503 ziwei_readings_unavailable(無法讀取解讀段落)。

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
404ziwei_not_enabled帳號未開通此功能
404ziwei_readings_not_enabled為 readings: true 但未開通解讀段落
400invalid_birth_date不存在的國曆日期,或農曆日、閏月超出範圍
400birth_time_required沒有 hour,會如上方範例一併回傳 partial
400reference_date_before_birthreferenceDate 早於出生日期
402INSUFFICIENT_BALANCE餘額不足
503ziwei_readings_unavailable無法讀取解讀段落

以上皆不計費。

八字特質(已包含於萬年曆)

自 2026-10-10 起,八字特質的內容會以萬年曆 API 回應中的 identity 欄位一併回傳:三災(samjae)、神煞(sinsal_list)、空亡(gongmang)、通根(rooting_hints)、季節強弱(season_strength_hint)、大運/流年時間軸(timeline)、八字 MBTI(mbti_inference)。除萬年曆價格外不另外收費。既有的 POST /api/v1/partners/v1/identity 會為已串接的合作夥伴暫時照常運作。新的串接請使用萬年曆。

  • 停用預告標頭:/identity 回應會附上 Deprecation: true 與 Link: </api/v1/partners/v1/manseryeok>; rel="successor-version"。終止日(Sunset)尚未決定。
  • 與萬年曆 identity 的差異:萬年曆回應中已有的鍵(saju、sipsin_map、strength、yongshin、gyeokguk、cheongan_detail、hap_chung_report、heoja_report、gongmang_detail、ohaeng_byeonsu_hits)不會出現在 identity 中。相同的值請從萬年曆的頂層欄位(wonkuk、strength、yongshinDetail、gyeokgukDetail 等)讀取。
  • currentYear、windowSize:萬年曆不接受這兩個參數(傳送時回傳 400)。若需要變更時間軸的基準年份或範圍,請暫時繼續使用 /identity。
  • 十神名稱是代碼值:sipsin_map(年、月、時的天干、地支,以及日支)的值(비견、정관 等)不論 lang 為何,都以韓文代碼值輸出。畫面上要顯示的名稱,請在萬年曆請求中傳送 glossary: true,使用所取得術語表(glossary,lang 語言)的翻譯。完整清單請參閱有效值 > 與語言無關的代碼值。
  • 出生時間不明:/identity 以正午計算,萬年曆的 identity 則與萬年曆本體相同,以年、月、日三柱為基準計算。/identity 以三柱為基準計算時(birthHour.basis = three_pillars),saju.hour 為 { "cheongan": "", "jiji": "", "ohaeng": null }(自 2026-10-16 起 ohaeng 為 null,代表沒有時柱)。五行數量不包含時柱。
  • 價格:既有的 /identity 為 ₩10/次(僅在帳號已開通時,未開通時回傳 404 identity_not_enabled)。萬年曆的 identity 不另外收費。使用量紀錄的 endpoint 為 identity。

POST /api/v1/partners/v1/identity(舊 endpoint)

請求本文與萬年曆 API 相同,另外接受 currentYear(1900~2200)、windowSize(1~10)。無法辨識 timezone 時,與萬年曆相同,回應會附上warnings。

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/identity \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{ "year": 1990, "month": 5, "day": 15, "hour": 12, "minute": 0, "timezone": "Asia/Seoul", "gender": "male" }'

回應範例(節錄,實際引擎輸出)

{
  "success": true,
  "data": {
    "saju": {
      "year":  { "cheongan": "경", "jiji": "오", "ohaeng": "금" },
      "month": { "cheongan": "신", "jiji": "사", "ohaeng": "금" },
      "day":   { "cheongan": "경", "jiji": "진", "ohaeng": "금" },
      "hour":  { ... }
    },
    "sipsin_map": { "year_cheongan": "비견", "year_jiji": "정관", "month_cheongan": "겁재", ... },
    "strength": { "dayMaster": "경", "score": -60, "result": "신약", "level": "중약", ... },
    "rooting_hints": { ... },
    "season_strength_hint": { "season": "여름", "strength_label": "최약(最弱)", ... },
    "sinsal_list": [ { "id": "shinsal_haksang", "name": "학당", "name_hanja": "學堂", "category": "길신", ... } ],
    "gongmang": { "sun": "갑술순", "void_branches": ["신", "유"], "hits": [] },
    "samjae": { "is_in_samjae": false, "current_year_branch": "오" },
    "yongshin": { "method": "조후", "primary": "수", ... },
    "timeline": { "current": { "daeun": { "startAge": 27, "endAge": 37, "stem": "갑", "branch": "신", ... }, ... } },
    "gyeokguk": { "primary": "비견격", ... },
    "mbti_inference": { "e_i": 48, "s_n": -8, "t_f": 16, "j_p": -18, "inferred": "ESFJ", ... },
    ...
  }
}

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
404identity_not_enabled帳號未開通
400INVALID_LUNAR_DATE · INVALID_LOCATION不存在的農曆日期/只傳送緯度、經度其中之一
402INSUFFICIENT_BALANCE餘額不足

八字↔MBTI 比較 API

POST /api/v1/partners/v1/saju-mbti

同時傳送出生資料與該人的 MBTI,就會回傳命盤(四柱,出生時間不明時為三柱),以及在 MBTI 4 個軸(E·I / S·N / T·F / J·P)上,將八字呈現的傾向與輸入的 MBTI 並列的比較。不使用 LLM,只做計算。每次價格與八字特質相同,為 ₩10/次(僅成功時計費)。

此解讀不是古典命理理論,而是現代的解讀慣例。自 kbVersion 2026.10.16-2 起,解讀規則為與現代文獻對照過的文獻版(回應中 interim: false、kbStatus: "literature")。為了不改變回應格式,這兩個欄位維持原樣。沒有文獻依據的暫定規則已退役,退役的規則 ID 不會再次使用。不判定哪一方正確或錯誤,也不判定類型之間的合盤。

  • 出生資料輸入:接受與萬年曆 API 相同的欄位(year、month、day、hour、minute、timezone、gender、calendar、isLeapMonth、地點校正等)。不接受 currentYear、windowSize(傳送時回傳 400)。
  • mbti(必填):4 字元字串("INFJ",不分大小寫,每個位置為 E/I · S/N · T/F · J/P),或各軸為 0~100 整數的物件 { "E_I": 30, "S_N": 45, "T_F": 80, "J_P": 60 }。100 代表前一個字母(E·S·T·J),50 以上即讀為前一個字母。以 4 字元傳送時,前一個字母換成 75、後一個字母換成 25,以「略微」強度處理。
  • 強度(band):|值 − 50| 未滿 10 為 balanced(均衡),10~25 為 slight(略微),超過 25 為 clear(明顯)。
  • 八字方面的傾向(sajuLean):依各軸,把符合日干、五行多寡(引擎判定)、突出的十神群組(同一群組 3 個位置以上)之規則的權重按字母加總,選出較大的一方。相同或沒有符合的規則時為 balanced。符合的規則 ID 在 ruleIds、matchedRules 中。
  • 比較(comparison):方向相同時為 relation: "same"(「與八字方向相同」),不同時為 "different"(「培養了與八字不同的一面」),任一方為 balanced 時為 "neutral"。文句(text)目前只有韓文。lang 只會反映在 birthHour.note。
  • 出生時間不明:省略 hour 時,以與八字特質相同的基準計算,並附上 birthHour。以三柱為基準時,wonkuk.hour 為 null,pillarCount 為 3。
  • 注意規則:caveatRuleId(R-MBTI-CAVEAT-001)與 caveats 中有「這是現代解讀,並非判定」的說明。請一併顯示在畫面上。
  • 使用量紀錄 endpoint:saju-mbti

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/saju-mbti \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{ "year": 1990, "month": 5, "day": 15, "hour": 12, "minute": 0, "timezone": "Asia/Seoul", "gender": "male", "mbti": "INFJ" }'

回應範例(節錄,實際引擎輸出)

{
  "success": true,
  "data": {
    "wonkuk": {
      "year":  { "cheongan": "경", "jiji": "오", "ohaeng": "금" },
      "month": { "cheongan": "신", "jiji": "사", "ohaeng": "금" },
      "day":   { "cheongan": "경", "jiji": "진", "ohaeng": "금" },
      "hour":  { "cheongan": "임", "jiji": "오", "ohaeng": "수" }
    },
    "pillarCount": 4,
    "dayMaster": "경",
    "strength": "신약",
    "ohaengCount": { "목": 0, "화": 3, "토": 1, "금": 3, "수": 1 },
    "ohaengState": { "목": "lack", "화": "balanced", "토": "lack", "금": "balanced", "수": "lack" },
    "dominantSipseong": ["관성"],
    "mbti": {
      "type": "INFJ",
      "source": "letters",
      "axes": {
        "E_I": { "value": 25, "letter": "I", "band": "slight" },
        "S_N": { "value": 25, "letter": "N", "band": "slight" },
        "T_F": { "value": 25, "letter": "F", "band": "slight" },
        "J_P": { "value": 75, "letter": "J", "band": "slight" }
      }
    },
    "sajuLean": {
      "E_I": { "lean": "balanced", "weights": { "E": 1, "I": 1 }, "ruleIds": ["R-MBTI-OHAENG-010", "R-MBTI-STRENGTH-002"] },
      "S_N": { "lean": "S", "weights": { "S": 1 }, "ruleIds": ["R-MBTI-OHAENG-006"] },
      "T_F": { "lean": "T", "weights": { "T": 2 }, "ruleIds": ["R-MBTI-STEM-007"] },
      "J_P": { "lean": "J", "weights": { "P": 1, "J": 2 }, "ruleIds": ["R-MBTI-OHAENG-008", "R-MBTI-SIPSEONG-002"] }
    },
    "comparison": [
      { "axis": "E_I", "label": "에너지 방향(E·I)", "user": "I", "userBand": "slight", "saju": "balanced", "relation": "neutral",
        "text": "에너지 방향(E·I): 사주에서는 어느 한쪽으로 기우는 경향이 뚜렷하지 않아요. 입력은 I 쪽이에요." },
      { "axis": "S_N", "label": "인식 방식(S·N)", "user": "N", "userBand": "slight", "saju": "S", "relation": "different",
        "text": "인식 방식(S·N): 사주와 다른 면을 키운 것으로 볼 수 있어요. 사주는 S 쪽 경향이 있고, 입력은 N 쪽이에요." },
      { "axis": "T_F", ... },
      { "axis": "J_P", "label": "생활 방식(J·P)", "user": "J", "userBand": "slight", "saju": "J", "relation": "same",
        "text": "생활 방식(J·P): 사주와 같은 방향이에요. 사주에서 보이는 J 쪽 경향이 입력에도 드러나요." }
    ],
    "matchedRules": [
      { "id": "R-MBTI-STEM-007", "statement": "庚 일간은 단단한 쇠의 기운으로 읽혀, 기준을 세워 따져 보고 결단하는 쪽(T)으로 기울기 쉬운 경향이 있어요." },
      ...
    ],
    "caveats": [ { "id": "R-MBTI-CAVEAT-001", "statement": "사주와 MBTI를 잇는 이 해석은 고전 명리 이론이 아니라 현대의 해석 관행이에요. ..." }, ... ],
    "caveatRuleId": "R-MBTI-CAVEAT-001",
    "interim": false,
    "kbStatus": "literature",
    "kbVersion": "2026.10.16-2",
    "engineVersion": "saju-mbti-1"
  }
}

錯誤代碼

除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
400(本文檢查)缺少 mbti、不是 4 個字元、軸值不是 0~100 的整數、未知的鍵
400INVALID_LUNAR_DATE · INVALID_LOCATION不存在的農曆日期/只傳送緯度、經度其中之一
402INSUFFICIENT_BALANCE餘額不足
404saju_mbti_not_enabled營運端關閉此功能時

今日運勢 API

POST /api/v1/partners/v1/today

將指定日期(預設:韓國時間今天)的日辰與本人的八字比對,回傳一日摘要(日辰、今日十神、今日模式 MBTI、今年運勢走勢分數、顯現的神煞、三災)與今日運勢(日辰與日干的關係、幸運色·食物·關鍵字、適合與應避開的時段、推薦活動、一句話訊息)。與 INTA – Life is Timing 應用程式首頁「今天」卡片的計算相同。活動適合度(taskAffinity)與一句今日走勢(summary.daily_flow)一律附上;傳送氣溫與天氣時會加上今日穿搭(fashion),mbtiBehavior: true 時還會加上今日模式 MBTI 行為模式(mbtiBehavior)。

請求參數

接受與萬年曆 API相同的出生資訊與選用選項(lang、農曆、座標、zaSiRule 等)。回應中的干支·五行代碼(summary.day_master·ilju 等)不論語言一律為韓文 — 請參閱代碼值表。無法辨識 timezone 時,與萬年曆相同,回應會附上 warnings。另外還接受:

參數型別必填說明
datestring要查看的日期 YYYY-MM-DD(1900-2100)。省略時為韓國時間的今天
temperatureCnumber目前氣溫(℃,−40~50)。傳送時回應會附上 fashion(早·午·晚穿搭)。省略時沒有 fashion(不做推估)
weatherstring天氣:clear · cloudy · rain · snow · storm
humiditynumber相對濕度(%,0~100)。必須同時傳送 temperatureC·weather·humidity 三個值,才會附上 fashion.mood(各時段一句天氣評語)
mbtiBehaviorboolean為 true 時附上 summary.today_mbti 的行為模式(mbtiBehavior)。預設 false

請求範例

{
  "year": 1990, "month": 5, "day": 15, "hour": 12, "minute": 0,
  "timezone": "Asia/Seoul", "gender": "male",
  "date": "2026-10-10",
  "temperatureC": 16, "weather": "cloudy", "humidity": 60,
  "mbtiBehavior": true
}

回應範例(實際引擎輸出,部分省略)

{
  "success": true,
  "data": {
    "date": "2026-10-10",
    "summary": {
      "ilju": "경진",
      "day_master": "경",
      "gyeokguk": "비견격",
      "gyeokguk_reason": "월지 사 중기(경) 투간 [연간=경]",
      "inferred_mbti": "ESFJ",
      "today_mbti": "ESFJ",
      "current_mbti": "ESFJ",
      "strength_label": "신약",
      "yongshin": "수",
      "today_date": "2026-10-10",
      "today_ganji": "정사",
      "today_day_ohaeng": "화",
      "today_sipsin": "정관",
      "flow_score": 60,
      "flow_tier": "good",
      "top_favored_task_type": "routine",
      "top_caution_task_type": "movement",
      "active_sinsal_names": ["학당", "암록", "복성귀인", "화개살", "자형(오오)"],
      "in_samjae": false,
      "daily_flow": "오늘(정사일) 화 에너지가 흘러 소통·확장에 유리해."
    },
    "omen": {
      "relation": { "type": "GEUK", "label": "조율의 날" },
      "color": { "name": "주황", "hex": "#FFA45B", "ohaeng": "화" },
      "food": "고추장비빔밥",
      "keyword": "공개",
      "message": "표현하고 싶은 마음과 주변 반응이 엇갈릴 수 있는 날이에요. 즉흥적인 말보다 한 박자 늦춘 표현이 좋아요.",
      "luckyHour": "오전 11시 ~ 오후 1시",
      "avoidHour": "밤 11시 이후",
      "activity": "칭찬 먼저 하기"
    },
    "taskAffinity": [
      { "taskType": "focus", "score": -0.25, "verdict": "neutral",
        "reason": "길 십신 2개 일치 · 흉 십신 2개 일치 · 일진 천간 정관(흉) · 일진 지지 편관(흉) · 천간합" },
      { "taskType": "creative", "score": -0.75, "verdict": "caution", "reason": "..." },
      ...,
      { "taskType": "routine", "score": 0.25, "verdict": "favored",
        "reason": "길 십신 4개 일치 · 일진 천간 정관(흉) · 일진 지지 편관(흉) · 천간합" }
    ],
    "fashion": {
      "temperatureC": 16, "tempBand": "T3",
      "main": "버건디 자켓", "accent": "가죽 벨트",
      "colorAttachLabel": "반지나 메탈 액세서리에",
      "byTime": {
        "morning": { "main": "버건디 자켓", "accent": "가죽 벨트", "tempBand": "T3" },
        "noon": { ... }, "evening": { ... }
      },
      "mood": {
        "feelsLikeC": 16, "tempBand": "jacket", "humidBand": "normal", "weatherKey": "cloudy",
        "morning": { "headline": "흐린 자켓 새벽", "body": "햇볕 없어 살짝 서늘. 자켓 한 벌.", "carry": [] },
        "noon": { ... }, "evening": { ... }
      }
    },
    "mbtiBehavior": {
      "mbti": "ESFJ",
      "headline": "협력·돌봄",
      "actions": ["약속·일정 챙기기 좋은 날", "주변에 도움 줄 수 있는 일 1개", "집·환경 정돈", "내 페이스도 지키기 — 다 떠안지 않기"],
      "closingLine": "주변과 결이 맞아 흐름이 부드러워요."
    }
  }
}
  • omen.relation.type 是本人日干與當天日辰天干之間的關係代碼:HAB(合)· SAENG(相生)· SAME(同五行)· GEUK(相剋)· CHUNG(沖)。label 是供人閱讀的名稱。
  • flow_score·flow_tier 是該年(流年)的走勢,today_mbti 是在本人八字 MBTI 上加入當天日辰的「今日模式」。
  • taskAffinity:7 種活動(focus·creative·contact·finance·organize·movement·routine)的今日適合度。各項目為 { taskType, score, verdict, reason },verdict 為 favored · neutral · caution。排列為引擎順序(非依分數排序)。
  • summary.daily_flow:一句今日走勢。summary.samjae_label:逢三災之年時的三災種類·階段(否則沒有)。
  • fashion:僅在傳送 temperatureC 時。fashion.mood:僅在 temperatureC·weather·humidity 全部傳送時。mbtiBehavior:僅在 mbtiBehavior: true 時(當天沒有 MBTI 模式則省略)。
  • 傳送 lang(en/ja/th)時,摘要中的格局·走勢、今日運勢,以及 taskAffinity·daily_flow·samjae_label·fashion·mbtiBehavior 字串都會翻譯。省略或 ko 則為韓文。
  • 相同出生資訊、相同 date(以及相同天氣輸入)時,結果永遠相同。出生時間不詳時以正午計算並附上 birthHour。以農曆輸入時會附上 lunarInput。

價格

  • ₩10/次呼叫。僅成功的呼叫計費,相同輸入的重複呼叫也會各自計費(冪等性)。
  • 輸入錯誤(400)、餘額不足(402)、計算失敗不計費。用量紀錄的 endpoint 為 today。

錯誤代碼

除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
404today_not_enabled帳號尚未開通此功能
400INVALID_LUNAR_DATE · INVALID_LOCATION不存在的農曆日期 / 緯度·經度只傳送其中一個
402INSUFFICIENT_BALANCE餘額不足

解夢 API

POST /api/v1/partners/v1/dream

從終端使用者描述的夢境中找出象徵詞(例:大海、魚),並依顯著程度排序回傳。詞語取自 HRUM 自行編製的夢境象徵詞庫(約 1,000 個日常名詞及其同義詞·活用形·口語說法)。詞庫只收錄詞語,不含解夢意義或吉凶判斷。回傳的詞語都是該詞或其同義詞·活用形實際出現在夢境內容中的。

請求參數

參數型別必填說明
dreamstring✓夢境內容(最多 1,000 字)
feelingstring夢中的感受(最多 300 字,例:「무섭고 답답했어요」—「又害怕又悶」)。與夢境內容合併後擷取標籤(合併後最多使用 1,000 字)
langstring回應語言。目前僅支援 ko(詞典僅有韓文)。其他值回傳 400
includeNegativeboolean 古籍依據中是否也納入凶的判斷(死亡、疾病、失去等)紀錄。預設 false。古籍依據開放前會被忽略

請求範例

{
  "dream": "바다에서 커다란 물고기를 두 손으로 잡는 꿈을 꿨어요"
}

回應範例

{
  "success": true,
  "data": {
    "lang": "ko",
    "mode": "glossary",
    "items": [
      { "keywords": ["바다"], "score": 1 },
      { "keywords": ["물고기"], "score": 0.979 },
      { "keywords": ["손"], "score": 0.749 }
    ]
  }
}
  • items 最多 40 個。一個項目 = keywords(象徵詞庫中的一個基本詞,例:「치아」(牙齒)、「앞니」(門牙)都是 ["이빨"])+ score。同一詞只出現一次。排列依夢中的顯著程度(越早出現、出現越多次、越具體的詞越前面),score 為 0~1,依清單順序相同或遞減(1 = 此夢中最顯著的象徵)。
  • mode:glossary(在象徵詞庫中找到)· none(沒有找到象徵)。feeling 也會與夢境內容一起搜尋。
  • 相同輸入會得到相同結果。不呼叫外部服務,直接在伺服器內計算。
  • 不包含解讀文字。若需要給終端使用者看的解讀,請將夢境內容與這些詞語傳入 AI 八字解讀(only: "dream")或 LLM 輸入中使用。
  • 2026-10-11 變更:舊回應的 title·meaning 欄位已移除,改為 keywords。同一天象徵詞的來源改為 HRUM 自有象徵詞庫,因此每個項目只有一個詞,mode 值變為 glossary · none 兩種(舊值 tags · fallback_char 不再出現)。

價格

  • ₩30/次呼叫。僅在找到一個以上項目時計費,結果為空(items: [])時為 ₩0。相同輸入的重複呼叫也會各自計費(冪等性)。
  • 輸入錯誤(400)、餘額不足(402)不計費。用量紀錄的 endpoint 為 dream。

古籍依據 kbMatches

回傳與夢境中出現的對象(天空、蛇、市場等)相符的解夢 KB 規則。依據為屬於公共領域的古代解夢書原文 — 敦煌本『周公解夢書』(P.3908,10 世紀)與『古今圖書集成』夢部。相同夢境內容永遠得到相同結果(不使用標籤服務·LLM 的文字比對規則)。

"kbMatches": [
  {
    "ruleId": "R-DREAM-DRAGON-002",
    "area": "DRAGON",
    "polarity": "positive",
    "status": "verified",
    "statement": "『주공해몽서』(돈황본 P.3908, 第十二 龍蛇章)는 뱀(虵=蛇)이 길에 있는 꿈(夢見虵當道者)에 대해 「大吉」라고 적는다(글자대로: 크게 길하다).",
    "quote": {
      "text": "夢見虵當道者大吉",
      "sourceId": "SRC-DREAM-P3908",
      "source": "『周公解夢書』 (敦煌 P.3908)",
      "location": "P.3908 第十二 龍蛇章 f09/左/行3下",
      "foundAt": "dream-pd/dunhuang-p3908-bnf/P3908-TRANSCRIPTION-merged.md:198"
    },
    "caveatRuleIds": [],
    "matchedTerms": ["구렁이", "길"]
  }
]
  • statement 是轉述原文如此記載的句子,並不是說夢境能預告未來。quote 是作為依據的原文一句及其位置。
  • polarity:依原文判斷部分分為 positive · negative · neutral。negative(死亡、疾病、失去等紀錄)僅在 includeNegative: true 時納入。
  • caveatRuleIds:該規則所附帶的注意規則(例:死亡·疾病紀錄為 R-DREAM-CAVEAT-002)。
  • 沒有相符規則時為空陣列。不計費的呼叫(例:items: [] 而為 ₩0 的呼叫)不會附上。

錯誤代碼

除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
404dream_not_enabled帳號尚未開通此功能
402INSUFFICIENT_BALANCE餘額不足

dream 為空或超過 1,000 字時回傳通用 400。沒有找到象徵並非錯誤,而是回傳 200 與 items: [](₩0)。

面相·手相測量 API

不傳送照片。傳送在合作夥伴裝置·瀏覽器上以 MediaPipe 擷取的座標(臉部 478 點 / 手部 21 點、手相線折線)後,伺服器會以相同的純函式計算測量鍵(比例·角度·區域),並回傳與該值相符的面相·手相 KB 規則(古代原文紀錄)。不使用 LLM,相同座標永遠得到相同結果。擷取座標的參考程式碼(瀏覽器 MediaPipe、Node、curl)請見參考程式碼頁面。模型名稱·版本·正規化·座標數量只要有一項與下列值不同,即回傳 400。

POST /api/v1/partners/v1/face-measure

參數型別必填說明
modelName, modelVersionstring✓產生座標的模型。不在允許清單內時回傳 400 MEASURE_MODEL_UNSUPPORTED / MEASURE_MODEL_VERSION_MISMATCH。目前:face_landmarker · float16/[email protected]
normalizationstring✓face-norm-1
landmarksnumber[][]✓正好 478 個 [x, y] 或 [x, y, z](除以影像寬·高的值,−0.02~1.02)
imageWidth, imageHeightnumber✓像素尺寸
hairline[number, number]臉部中央髮際線的一點。伺服器不做推估 — 沒有時上停相關的鍵為 null(原因 hairline_missing)。建議讓使用者點選額頭上方頭髮開始的位置(頭髮分割模型僅供參考)
qualityobjectyawDeg·pitchDeg·rollDeg·blendshapes(MediaPipe 係數名稱→分數)。必須傳送才會進行品質檢查
includeNegativeboolean是否也納入凶的判斷紀錄(polarity negative)。預設 false(與解夢相同的名稱·意義)

POST /api/v1/partners/v1/palm-measure

參數型別必填說明
modelName, modelVersionstring✓目前:hand_landmarker · float16/[email protected]
normalizationstring✓palm-norm-1
landmarksnumber[][]✓正好 21 個
imageWidth, imageHeightnumber✓像素尺寸
handednessstring✓left | right — 被拍攝者實際的手(請讓使用者選擇)
mirroredboolean左右翻轉的照片(自拍預覽)時為 true
creasesobject[]手相線折線(最多 64 條,每條 2~512 點)。欄位:points(✓)、label(life·head·heart·fate·sun·mercury·simian·unknown)、kind(segment | branch)、autoLabel。沒有時線相關的鍵為 null(creases_missing)
autoLabelboolean以伺服器共用的啟發式規則為所有未命名的線命名。若只要用於某一條線,請在該項目指定 autoLabel。自行指定的 label 永遠優先
includeNegativeboolean與臉部相同。預設 false
  • 線段請在傳送前先接起來。伺服器不會連接線段,啟發式規則每條線只會為一個線段命名。在與其他線交叉處被切斷的線段(例:與命運線相交的感情線),必須像參考程式碼 stitch_creases.py 一樣先接起來再傳送,才會被命名。肉眼可見的實際斷裂請保持斷開(斷裂數以 breaks 鍵計算)。

請求範例(臉部,節錄)

{
  "modelName": "face_landmarker",
  "modelVersion": "float16/[email protected]",
  "normalization": "face-norm-1",
  "landmarks": [[0.5012, 0.3121, -0.031], … 478개 …],
  "imageWidth": 1080,
  "imageHeight": 1350,
  "hairline": [0.501, 0.182],
  "quality": { "yawDeg": 2.1, "pitchDeg": -3.4, "blendshapes": { "eyeBlinkLeft": 0.05, "jawOpen": 0.02 } }
}

回應範例(開頭節錄)

{
  "success": true,
  "data": {
    "normalization": "face-norm-1",
    "keys": { "face.thirds.upper_ratio": 0.3333, "face.brow.length_vs_eye": 1.625, "face.brow.outer_overhang": 0.1648, … },
    "reasons": {},
    "quality": { "rollDeg": 0, "iodPx": 158, "flags": [] },
    "kbMatches": [
      {
        "ruleId": "R-FACE-PALACE-031",
        "area": "PALACE",
        "kind": "interpretation",
        "polarity": "positive",
        "status": "verified",
        "statement": "『古今圖書集成』 相術部彙考 「十二宮訣」 兄弟는 눈썹이 눈보다 길게 지나가면(眉長過目) …라고 적는다 …",
        "quote": { "text": "眉長過目,三四兄弟", "sourceId": "SRC-FACE-HUIKAO", "source": "…", "location": "…", "foundAt": "…" },
        "caveatRuleIds": ["R-FACE-CAVEAT-001"],
        "matchedConditions": [{ "key": "face.brow.outer_overhang", "op": "gt", "value": 0, "actual": 0.1648 }]
      }
    ]
  }
}
  • keys:所有測量鍵(鍵的定義·計算式·可信度請見鍵表文件)。無法產生值時為 null,原因列於 reasons:hairline_missing · blink · smile · jaw_open · finger_bent · creases_missing · back_of_hand(手背照片 — 僅線相關的鍵)等。
  • missingSections:值為 null 的測量鍵數量(鍵與原因見 keys·reasons)。為 0 表示所有鍵都有值。
  • kbMatches:只納入原文直接給出數值·比較的規則。僅能以我們自訂門檻判定的規則,在依據實測(PoC)完成前不納入。statement 是原文如此記載的紀錄,並非預言·診斷。negative 僅在 includeNegative: true 時。
  • 品質:頭部轉動·低頭超過 10°(MEASURE_QUALITY_POSE)或臉部太小(MEASURE_QUALITY_FACE_SIZE)時,整個請求回傳 400 — 請引導使用者重新拍攝。閉眼·微笑·張嘴不會回傳 400,只有相關的鍵為 null。
  • 輸入錯誤以 400 與代碼(MEASURE_LANDMARK_COUNT · MEASURE_COORD_RANGE · MEASURE_COORD_NAN · MEASURE_CREASE_LIMIT 等)回傳。錯誤訊息只包含點的編號,不含座標值。
  • 顯示凶的紀錄時(includeNegative: true):statement 是原文如此記載的紀錄。請以「原文記載有這樣的傾向 + 可以這樣應對」的方式傳達給使用者,不要改寫成貶低他人或替性格貼標籤的說法。

錯誤代碼

HTTP代碼意義
400MEASURE_MODEL_UNSUPPORTEDmodelName 不在允許清單內
400MEASURE_MODEL_VERSION_MISMATCHmodelVersion 不在允許清單內(目前僅 float16/[email protected])
400MEASURE_NORMALIZATION_MISMATCHnormalization 不是 face-norm-1 / palm-norm-1
400MEASURE_LANDMARK_COUNT座標數量不是臉部 478 / 手部 21
400MEASURE_LANDMARK_SHAPE · MEASURE_COORD_NAN · MEASURE_COORD_RANGE · MEASURE_IMAGE_SIZE · MEASURE_DEGENERATE點的格式·數值·範圍(−0.02~1.02)·影像尺寸錯誤
400MEASURE_HANDEDNESS · MEASURE_CREASE_LIMIT · MEASURE_CREASE_SHAPE · MEASURE_CREASE_LABEL手部·手相線輸入錯誤
400MEASURE_QUALITY_POSE · MEASURE_QUALITY_FACE_SIZE頭部轉動超過 10° · 臉部太小 — 請重新拍攝
400(驗證錯誤)傳送了文件中沒有的欄位 — 請只傳送允許的欄位
402INSUFFICIENT_BALANCE點數餘額不足
404face_measure_not_enabled · palm_measure_not_enabled尚未開放的功能

所有錯誤回應皆不計費。

個人資料

  • 不接收照片。照片在使用者裝置上轉換為座標,API 只會收到座標。
  • 不儲存座標。座標屬於臉部·手部的幾何資訊,伺服器僅在處理請求期間於記憶體中使用,不會留在日誌·資料庫·錯誤訊息中。用量紀錄只留下 endpoint·狀態·金額。
  • 終端使用者的同意請由合作夥伴取得。
  • 參考程式碼使用的 MediaPipe 採用 Apache-2.0 授權,可能會傳送使用統計。整合到產品中時,請一併發布授權聲明,並反映在隱私權政策中。

價格

  • 面相測量 ₩30 /次呼叫,手相測量 ₩30 /次呼叫(VAT 另計 · 含 VAT ₩33)。
  • 僅在產生一個以上測量鍵時計費。完全沒有測量鍵時為 ₩0,輸入·品質錯誤(400)、餘額不足(402)、未開放(404)也不計費。用量紀錄的 endpoint 為 face-measure / palm-measure。
  • 手相測量中被判定為手背照片時(quality.flags 含 back_of_hand),所有鍵為 null(原因 back_of_hand),KB 規則也為空,且不計費(₩0)。請改用手掌面的照片,並以正確的 handedness·mirrored 重新傳送。手背判定是將手腕·食指根部·小指根部座標的旋轉方向與 handedness·mirrored 比對。
  • 即使部分鍵為 null,價格也相同。缺少的鍵數量會以 missingSections 告知。

面相·手相解讀 API(照片)

以一張臉部照片解讀面相,以一張手掌照片解讀手相。照片只在伺服器記憶體中處理,不會儲存。面相也可以不傳照片,改傳與面相測量相同的座標(landmarks)— 此時不使用照片即可找出測量鍵與 KB 規則,並由 AI 為每條規則以淺顯的文字撰寫解讀(面相解讀一律包含 AI 解讀。若只需要不含 AI 的測量,請使用面相測量)。結果是以娛樂與參考為目的解讀傳統面相·手相的內容,並非事實判斷或診斷。

解讀文字目前僅有韓文,即使傳送其他 lang 也會以韓文回答(回應的 lang 一律為 "ko")。

POST /api/v1/partners/v1/face-reading

參數型別必填說明
imageobject二擇一{ data, mimeType } — data 為照片位元組的 base64(解碼後最多 8MB),mimeType 為 image/jpeg · image/png · image/webp。格式會再以位元組確認(不符則回傳 400)
landmarksobject二擇一與面相測量請求本文相同(modelName · modelVersion · normalization · landmarks 478 點 · imageWidth · imageHeight · hairline · quality · includeNegative)
consentobject照片時 ✓照片處理同意 — 請見下方同意物件
llmboolean不必傳送 — 一律包含 AI 解讀。傳送 false 會回傳 400 USE_FACE_MEASURE(不含 AI 的測量請用面相測量)
langstring接受 ko · en · ja · th,但解讀文字目前僅有韓文(回應的 lang = "ko")
endUserIdstring合作夥伴使用的終端使用者 ID(最多 255 字)。只會記錄在用量紀錄中

image 與 landmarks 只能傳送其中一個。兩者都傳或都沒傳時回傳 400 READING_INPUT_ONE_OF。

請求範例(面相,照片)

{
  "image": { "data": "/9j/4AAQSkZJRgABAQ…(base64)", "mimeType": "image/jpeg" },
  "consent": { "photo": true, "version": "photo-consent-2026-10", "subject": "end_user" },
  "lang": "ko",
  "endUserId": "member-1024"
}

POST /api/v1/partners/v1/palm-reading

參數型別必填說明
imageobject✓一張手掌面的照片。格式·大小與面相相同
consentobject✓同意物件
creasesobject[]使用者在照片上描繪的手相線(最多 16 條)。欄位:line(life · head · heart · fate · sun · mercury · simian · unknown)、points([x, y] 2~256 個,以照片左上角為基準的 0~1)。尋找線的位置時會優先參考
langstring與面相相同(解讀文字目前僅有韓文)
endUserIdstring與面相相同

請求範例(手相,含描繪的線)

{
  "image": { "data": "/9j/4AAQSkZJRgABAQ…(base64)", "mimeType": "image/jpeg" },
  "consent": { "photo": true, "version": "photo-consent-2026-10", "subject": "end_user" },
  "creases": [
    { "line": "life", "points": [[0.42, 0.38], [0.36, 0.52], [0.34, 0.71]] },
    { "line": "heart", "points": [[0.78, 0.33], [0.6, 0.31], [0.47, 0.34]] }
  ]
}

例:"consent": { "photo": true, "version": "photo-consent-2026-10", "subject": "end_user" }

  • photo:必須為 true — 表示使用者已同意照片處理。
  • version:合作夥伴顯示的同意文字版本(1~40 字)。
  • subject:end_user(使用者本人的照片)· third_party(他人的照片 — 該人的同意也請由合作夥伴取得)。
  • 沒有或值不正確時回傳 400 CONSENT_REQUIRED。用量紀錄只會留下 version 與 subject。

照片處理

  • 照片只在處理請求期間於記憶體中使用。不會留在磁碟·資料庫·日誌·檔案儲存空間,也不會產生或儲存臉部·手部特徵值(範本·嵌入向量)。不會辨識身分,也不會與其他照片比對。
  • 傳送給外部模型前,會刪除 EXIF(含位置·裝置資訊)·XMP·ICC 等中繼資料,並重新產生長邊 1600px 以下的 JPEG。WebP 只刪除中繼資料後原樣傳送,因此只接受長邊 1600px 以下的檔案(更大則回傳 413 — 請縮小或改以 JPEG·PNG 傳送)。
  • 每張照片呼叫外部模型兩次:先分類照片(是否為臉部·手掌、是否只有一人、是否看起來未成年、畫質),通過時才撰寫解讀。兩次呼叫都使用 store: false。
  • 看起來未成年(未滿 18 歲)的照片不會解讀。出現多人·兩隻以上的手的照片,以及不是臉部·手掌的照片也一樣(400 IMAGE_NOT_ALLOWED)。手背照片回傳 400 PALM_NOT_DETECTED。拍攝手相時請讓畫面中只有一隻手掌。即使只拍到另一隻手的一點指尖,也可能被視為兩隻手而遭拒絕。
  • 外部模型:傳送至 OpenAI(美國)。以 store: false 傳送,OpenAI 不會將 API 輸入用於訓練,並為了濫用監控最多保存 30 天後刪除。回應的 meta.processing 會以固定格式載明相同內容。
  • 解讀中不會包含健康·疾病·壽命、種族·民族·國籍·膚色、年齡、犯罪·道德、身分·相似的人、性傾向·宗教、斷定性格·命運的說法。透過模型指示加以防止,並在回應中再過濾一次相關句子。

回應的 meta.processing 為固定格式(以照片解讀時):

"processing": {
  "provider": "OpenAI",
  "model": "gpt-5.6-luna",
  "region": "US",
  "store": false,
  "retention": "API 입력은 학습에 쓰지 않음, 오남용 감시로 최대 30일 보관 뒤 삭제",
  "imageStored": false
}

未呼叫外部模型的回應(以 landmarks 找不到任何測量鍵或相符的 KB 紀錄而以 ₩0 結束的情況),provider · model · region · store · retention 為 null,imageStored 為 false。

回應範例(面相,照片)

{
  "success": true,
  "data": {
    "items": [
      {
        "key": "forehead",
        "label": "이마",
        "observation": "이마가 넓고 둥글게 보여요.",
        "reason": "넓은 이마는 생각을 넓게 펼치는 쪽으로 읽혀요. 떠오른 계획을 글로 정리해 두면 장점이 더 살아나요."
      },
      {
        "key": "eyes",
        "label": "눈",
        "observation": "눈매가 길고 가로로 뻗어 있어요.",
        "reason": "긴 눈매는 사람과 상황을 찬찬히 살피는 쪽으로 읽혀요."
      }
    ],
    "summary": "생각을 넓게 펼치고 찬찬히 살피는 인상으로 읽혀요.",
    "lang": "ko",
    "meta": {
      "input": "image",
      "processing": { "provider": "OpenAI", "model": "gpt-5.6-luna", "region": "US", "store": false, "retention": "API 입력은 학습에 쓰지 않음, 오남용 감시로 최대 30일 보관 뒤 삭제", "imageStored": false },
      "disclaimer": "entertainment_reference",
      "disclaimerText": "전통 관상·손금·성명학을 재미와 참고로 풀어 본 내용이에요. 사실 판단이나 진단이 아니에요.",
      "kbRuleIds": []
    }
  }
}
  • items:只包含照片中可見的部位。面相 key:face_shape · forehead · eyebrows · eyes · nose · mouth · ears · chin。手相 key:hand_shape · fingers · life_line · head_line · heart_line · fate_line · sun_line · mounts。label 以韓文回傳。
  • 以 landmarks 傳送的面相,會以相同名稱一併回傳面相測量的回應欄位(normalization · keys · reasons · quality · kbMatches · missingSections),items 每條 KB 規則一個。與照片解讀相同,label 是部位名稱(眉毛 · 眼睛 · 鼻子 …),reason 是 AI 以淺顯文字撰寫的解讀,並一併附上 key(測量鍵)· ruleId · polarity · source(作為解讀基礎的 KB 規則文字)。meta.kbRuleIds 彙整了依據規則的 ID。
  • meta.disclaimer 一律為 entertainment_reference。請在使用者畫面上一併顯示 meta.disclaimerText(或意義相同的文字)。

錯誤代碼

HTTP代碼意義
400READING_INPUT_ONE_OF面相:image 與 landmarks 不是正好只有一個
400IMAGE_REQUIRED手相:沒有 image
400CONSENT_REQUIRED傳送照片但沒有 consent 或值不正確
400IMAGE_INVALID · IMAGE_FORMAT_UNSUPPORTED無法讀取的照片 · mimeType 與實際格式不同 · 不是 JPEG·PNG·WebP(含動態 WebP)
413IMAGE_TOO_LARGE照片超過 8MB · 超過 8192px 或 1680 萬像素 · WebP 長邊超過 1600px
400IMAGE_NOT_ALLOWED看起來未成年 · 多張臉 / 兩隻以上的手 · 不是臉部·手掌照片
400FACE_NOT_DETECTED · PALM_NOT_DETECTED找不到臉部 / 手掌(手背照片為 PALM_NOT_DETECTED)
400USE_FACE_MEASURE面相 landmarks 搭配 llm: false — 不含 AI 的測量請用面相測量 API
400MEASURE_LOW_QUALITY模糊 · 太暗 · 被遮住 · 太小 · 傾斜 — 原因列於回應的 quality。請引導使用者重新拍攝
400CREASE_INVALID手相線的點少於 2 個或超出 0~1 範圍
400MEASURE_*landmarks 輸入錯誤(與面相測量相同的代碼)
402INSUFFICIENT_BALANCE餘額不足 — 在呼叫外部模型前確認
404face_reading_not_enabled · palm_reading_not_enabled尚未開放的功能
409IDEMPOTENCY_KEY_REUSED · IDEMPOTENCY_IN_PROGRESS同一個 X-Idempotency-Key 用於不同本文 · 同一金鑰的第一個請求仍在處理中(請見下方重試與重新傳送)
429FILTERED_QUOTA_EXCEEDED今日被過濾的照片已達每日上限 — 請見下方被過濾照片的每日上限
502READING_UNAVAILABLE無法產生解讀(含輸出被截斷的情況) — 請重試
503IMAGE_BUSY照片處理繁忙 — 請稍後再試
504LLM_UPSTREAM_TIMEOUT外部模型回應逾時

計費

  • 價格請見價目表。僅 200 回應計費,4xx·5xx 錯誤與失敗一律為 ₩0(含被過濾的照片、輸出被截斷的 502)。找不到任何測量鍵或相符 KB 紀錄的 landmarks 呼叫也是 ₩0。
  • 用量紀錄的 endpoint 為 face-reading / palm-reading。
  • 照片 API 只能以伺服器金鑰呼叫(應用程式專用的「AI 連線」金鑰會回傳 403 APP_KEY_SCOPE)。照片請經由合作夥伴的伺服器傳送。

被過濾照片的每日上限

經過分類後被過濾的照片(IMAGE_NOT_ALLOWED · FACE_NOT_DETECTED · PALM_NOT_DETECTED · MEASURE_LOW_QUALITY)以及輸出被截斷而產生的 502,對合作夥伴是 ₩0,但會產生外部模型費用。因此每個合作夥伴在韓國時間一天(00:00~24:00)內,最多只接受 200 件與當天成功的照片解讀數 3 倍之中較大的值。超過時會在呼叫外部模型前以 429 FILTERED_QUOTA_EXCEEDED(₩0,本文含 filtered · limit)回應,並於隔天 00:00(KST)解除。先向使用者顯示拍攝指引(正面·明亮·單人·手掌面),可減少被過濾的照片。landmarks 呼叫不計入。

重試與重新傳送(X-Idempotency-Key)

網路中斷後重新傳送時,請加上 X-Idempotency-Key 標頭(1~128 字,可列印的 ASCII)。同一合作夥伴在 24 小時內以相同金鑰與相同本文(含照片)重新傳送時,會原樣回傳第一次的結果 — 不會重新計費,也不會呼叫外部模型,回應會附上 Idempotent-Replayed: true 標頭。

  • 同一金鑰搭配不同本文:409 IDEMPOTENCY_KEY_REUSED(₩0) — 新請求請使用新金鑰。
  • 同一金鑰的第一個請求仍在處理中:409 IDEMPOTENCY_IN_PROGRESS(₩0) — 請在幾秒後以相同金鑰重新傳送。
  • 只儲存已計費的 200 結果。若回應為錯誤或 ₩0,以相同金鑰重新傳送時會重新處理。
  • 儲存的只有金鑰的雜湊、本文的雜湊與加密後的結果,24 小時後刪除。不儲存照片。
  • 沒有標頭時,與目前相同,每個請求都會處理並計費。

姓名學 API

以姓名(韓文,若知道漢字也可附上漢字)與選填的出生年月日,回傳姓名學解讀。回應分為程式計算的 deterministic(發音五行·筆畫數·81 數理四格·字源五行·用神補足),以及 AI 僅根據這些值撰寫的 interpretation。每項計算都附有作為依據的姓名學 KB 規則 ID。結果是以娛樂與參考為目的解讀傳統姓名學的內容。

  • 姓名解讀(預設):計算 + AI 解讀。姓名會傳送至 OpenAI(美國),因此需要 consent。
  • 姓名計算("interpret": false):僅計算,不呼叫 AI。interpretation 為 null,不需要 consent。兩者價格不同(價目表)。
  • 解讀文字目前僅有韓文,即使傳送其他 lang 也會以韓文回答(回應的 lang = "ko")。

POST /api/v1/partners/v1/naming

參數型別必填說明
name.hangulstring✓2~6 個音節的韓文姓名,姓氏在前(例:김하늘)。남궁(南宮)、황보(皇甫)、제갈(諸葛)、선우(鮮于)、독고(獨孤)、사공(司空)、서문(西門)、동방(東方)視為兩字姓氏
name.hanja(string|null)[]每個音節一個漢字,不知道則為 null。長度與音節數不同時回傳 400 NAME_HANJA_LENGTH
name.strokes(number|null)[]每個音節的原筆畫數(以原字為準)(1~64),不知道則為 null(見下方筆畫數說明)
name.meanings(string|null)[]每個音節的漢字字義(訓,例:물(水)· 쇠(金屬),1~20 字)。字源五行只依此字義判斷
birthobject{ year, month, day, hour?, minute?, gender?, timezone? }(國曆)。傳送時會計算八字用神,查看姓名是否補足該五行。timezone 預設 Asia/Seoul。出生年月日不會傳送給外部模型
interpretboolean預設 true(姓名解讀)。false 時僅做姓名計算(不含 AI)
echoNameboolean2026-10-31 新增。預設 true(與目前相同)。false 時回應中任何地方都不再寫出姓名文字 — name 為 null,deterministic.syllables 的 hangul·hanja·meaning 為 null,改附上 position(從 1 開始)。items 中的文字標示也會改為「첫 글자(목(木))」(「第一個字(木(木))」)這樣的位置表示;若為姓名解讀,姓名本身不會傳送給 AI(只傳送計算值與位置)
consentobject姓名解讀時 ✓{ "version": "name-consent-2026-10", "subject": "end_user" } — version 為合作夥伴顯示的同意文字版本(1~40 字),subject 為 end_user · third_party。沒有或值不正確時回傳 400 CONSENT_REQUIRED。用量紀錄只會留下 version 與 subject。interpret: false 時不需要
langstring接受 ko · en · ja · th,但目前只以韓文回答
endUserIdstring合作夥伴的終端使用者 ID(僅用於用量紀錄)
  • 筆畫數以原筆畫數(以原字為準)計算(例:氵以水計為 4 畫)。伺服器知道筆畫數的漢字只有 38 個姓氏用字(R-NAME-STROKE-004),其中各字典數值不一的 11 個字(洪·沈·河·池·鄭·郭·陳·權·禹·羅·尹)以 strokeNote: "disputed" 留空。其他漢字必須以 name.strokes 傳送原筆畫數,才會得出四格。只要有一個音節沒有筆畫數,就是 suri: null、suriMissing: "strokes_unknown"。
  • 發音五行依初聲決定,採用喉音(ㅇ·ㅎ)= 土、唇音(ㅁ·ㅂ·ㅍ)= 水的配屬(R-NAME-SOUND-011)。

請求範例

{
  "name": { "hangul": "김민수", "hanja": ["金", "民", "秀"], "strokes": [null, 5, 7], "meanings": ["쇠", null, null] },
  "birth": { "year": 1990, "month": 5, "day": 17, "hour": 9 },
  "consent": { "version": "name-consent-2026-10", "subject": "end_user" }
}

若只需要姓名計算,請加入 "interpret": false,consent 可以省略。此時回應的 interpretation 為 null,meta.processing 的外部模型項目也為 null。

回應範例(節錄)

{
  "success": true,
  "data": {
    "name": { "hangul": "김민수", "hanja": ["金", "民", "秀"] },
    "deterministic": {
      "surnameLength": 1,
      "syllables": [
        { "index": 0, "hangul": "김", "hanja": "金", "strokes": 8, "strokeSource": "kb", "strokeNote": null, "strokeRuleId": "R-NAME-STROKE-004", "soundElement": "wood", "soundRuleId": "R-NAME-SOUND-004", "meaning": "쇠", "rootElement": "metal" },
        { "index": 1, "hangul": "민", "hanja": "民", "strokes": 5, "strokeSource": "input", "strokeNote": null, "strokeRuleId": null, "soundElement": "water", "soundRuleId": "R-NAME-SOUND-010", "meaning": null, "rootElement": null },
        { "index": 2, "hangul": "수", "hanja": "秀", "strokes": 7, "strokeSource": "input", "strokeNote": null, "strokeRuleId": null, "soundElement": "metal", "soundRuleId": "R-NAME-SOUND-006", "meaning": null, "rootElement": null }
      ],
      "soundFlow": { "elements": ["wood", "water", "metal"], "relations": ["reverse_generating", "reverse_generating"], "generating": 0, "overcoming": 0, "score": 0.5 },
      "suri": {
        "won": { "sum": 12, "number": 12, "grade": "bad" },
        "hyung": { "sum": 13, "number": 13, "grade": "good" },
        "i": { "sum": 15, "number": 15, "grade": "good" },
        "jeong": { "sum": 20, "number": 20, "grade": "bad" }
      },
      "suriMissing": null,
      "yongshin": { "element": "wood", "supplied": true, "suppliedBy": ["sound"] },
      "kbRuleIds": ["R-NAME-JAWON-001", "R-NAME-MODERN-001", "R-NAME-MODERN-003", "R-NAME-SOUND-004", "R-NAME-SOUND-006", "R-NAME-SOUND-010", "R-NAME-SOUND-011", "R-NAME-STROKE-004"]
    },
    "interpretation": { "text": "첫 글자는 목, 가운데 글자는 수, 끝 글자는 금 기운이에요. 소리가 서로 부딪치지 않고 이어지는 이름으로 읽혀요." },
    "items": [
      { "key": "sound_flow", "label": "발음오행 흐름", "score": 0.5, "reason": "김(목(木)) → 민(수(水)) → 수(금(金)) · 상생 0 · 상극 0", "ruleId": "R-NAME-SOUND-011" },
      { "key": "suri_hyung", "label": "형격", "grade": "good", "score": 13, "reason": "획수 합 13 → 13수(길)", "ruleId": "R-NAME-MODERN-001" },
      { "key": "yongshin_match", "label": "용신 보완", "grade": "supplied", "reason": "용신 목(木)을 이름이 발음으로 채워 줘요" }
    ],
    "summary": "부드럽게 이어지는 소리에 용신 기운이 담긴 이름으로 읽혀요.",
    "lang": "ko",
    "meta": {
      "input": "name",
      "processing": { "provider": "OpenAI", "model": "gpt-5.6-luna", "region": "US", "store": false, "retention": "API 입력은 학습에 쓰지 않음, 오남용 감시로 최대 30일 보관 뒤 삭제", "imageStored": false },
      "disclaimer": "entertainment_reference",
      "disclaimerText": "전통 관상·손금·성명학을 재미와 참고로 풀어 본 내용이에요. 사실 판단이나 진단이 아니에요.",
      "kbRuleIds": ["R-NAME-JAWON-001", "R-NAME-MODERN-001", "R-NAME-MODERN-003", "R-NAME-SOUND-004", "R-NAME-SOUND-006", "R-NAME-SOUND-010", "R-NAME-SOUND-011", "R-NAME-STROKE-004"]
    }
  }
}
  • 五行值:wood · fire · earth · metal · water。關係:generating(相生)· overcoming(相剋)· same(比和)· reverse_generating(後者生前者)。
  • 81 數理 grade:good(吉)· mixed(半吉半凶)· bad(凶)。81 數理吉凶表是沒有古典原典的現代慣例(R-NAME-MODERN-001)。
  • items 是將 deterministic 以與其他畫面相同的形式(key · label · grade · score · reason · ruleId)排列的內容。四格只在筆畫數齊全時納入。
  • 解讀文字不會以引號引用姓名文字,也不會逐字點出(2026-10-31 新增)。文字只以「第一個字 · 中間的字 · 最後一個字」這樣的位置來說明。伺服器會檢查結果,若出現以引號框住姓名文字或寫出整個姓名的句子,會以更嚴格的指示只重寫一次(不額外計費)。若仍有殘留,會將該部分替換為位置用語(「‘김’과」 → 「첫 글자와」,即「‘金’和」→「第一個字和」)以及「이 이름」(「這個名字」)後再回傳。沒有引號的單一文字(例:像助詞一樣常見的字)無法與一般詞語區分,因此不替換。
  • "echoName": false 回應範例(2026-10-31 新增,節錄) — 用於不顯示姓名、只顯示結果時。
    "name": null,
    "deterministic": {
      "syllables": [
        { "index": 0, "position": 1, "hangul": null, "hanja": null, "strokes": 8, "strokeSource": "kb", "soundElement": "wood", "meaning": null, "rootElement": "metal", ... },
        { "index": 1, "position": 2, "hangul": null, "hanja": null, "strokes": 5, "soundElement": "water", "meaning": null, ... },
        { "index": 2, "position": 3, "hangul": null, "hanja": null, "strokes": 7, "soundElement": "metal", "meaning": null, ... }
      ], ...
    },
    "items": [
      { "key": "sound_flow", "label": "발음오행 흐름", "score": 0.5, "reason": "첫 글자(목(木)) → 가운데 글자(수(水)) → 끝 글자(금(金)) · 상생 0 · 상극 0", "ruleId": "R-NAME-SOUND-011" }, ...
    ]

錯誤代碼

HTTP代碼意義
400NAME_INVALID韓文姓名不是 2~6 個音節 · hanja/strokes/meanings 值的格式錯誤
400NAME_HANJA_LENGTHhanja 長度與音節數不同
400CONSENT_REQUIRED姓名解讀但沒有 consent 或值不正確
400(驗證錯誤)不存在的日期 · 文件中沒有的欄位
402INSUFFICIENT_BALANCE餘額不足
404naming_not_enabled尚未開放的功能(姓名解讀·姓名計算分別開放)
409IDEMPOTENCY_KEY_REUSED · IDEMPOTENCY_IN_PROGRESS同一個 X-Idempotency-Key 用於不同本文 · 同一金鑰的第一個請求仍在處理中(請見下方重試與重新傳送)
502READING_UNAVAILABLE無法產生 AI 解讀 — 不計費(也沒有只回傳計算結果的部分計費)。請重試
504LLM_UPSTREAM_TIMEOUT外部模型回應逾時

計費

  • 價格請見價目表(姓名計算 · 姓名解讀)。僅 200 回應計費,4xx·5xx 錯誤與失敗一律為 ₩0。用量紀錄的 endpoint 兩者皆為 naming。也可以用應用程式專用的「AI 連線」金鑰呼叫。

重試與重新傳送(X-Idempotency-Key)

重新傳送時,請加上 X-Idempotency-Key 標頭(1~128 字,可列印的 ASCII)。同一合作夥伴在 24 小時內以相同金鑰與相同本文重新傳送時,會原樣回傳第一次的結果 — 不會重新計費,也不會呼叫 AI,回應會附上 Idempotent-Replayed: true 標頭。

  • 同一金鑰搭配不同本文:409 IDEMPOTENCY_KEY_REUSED(₩0) — 新請求請使用新金鑰。
  • 同一金鑰的第一個請求仍在處理中:409 IDEMPOTENCY_IN_PROGRESS(₩0) — 請在幾秒後以相同金鑰重新傳送。
  • 只有已計費的 200 結果會連同金鑰的雜湊·本文的雜湊加密後保存 24 小時。若回應為錯誤或 ₩0,以相同金鑰重新傳送時會重新處理。沒有標頭時,與目前相同,每個請求都會處理並計費。
  • meta.disclaimer 為 entertainment_reference。請在使用者畫面上一併顯示 meta.disclaimerText。

塔羅 API

POST /api/v1/partners/v1/tarot

指定張數(count,1~10 張)或牌陣(spread)後,會從 78 張牌組(大阿爾克那 22 張 · 小阿爾克那 56 張)中不重複地抽牌,並為每張牌回傳正位·逆位、關鍵字、牌義、牌卡圖片網址。沒有 AI 解讀 — 牌義就是該牌固定的文字。因此使用方式有三種。

請求參數

參數型別必填說明
countnumber△要抽的張數 1~10(整數)。count 與 spread 只能傳送其中一個。兩者都傳或都沒傳時回傳 400
spreadstring△牌陣。張數與位置名稱都是固定的:single(今日一張,1 張)· past-present-future(過去·現在·未來,3 張)· choice(選擇:目前狀況·阻礙·結果,3 張)· celtic-condensed(凱爾特簡化版,5 張)· future-prediction(未來預測,5 張)
reversedboolean是否允許逆位(預設 true)。false 時全部為正位
seedstring用於重現的字串(1~200 字)。相同 seed + 相同 count/spread + 相同 reversed 時,永遠抽出相同的牌。沒有時每次隨機(密碼學亂數)
questionstring終端使用者的問題(最多 500 字)。不用於解讀,會原樣回傳於回應中 — 這是為了方便傳給下一個 LLM 步驟而設的欄位
langstring牌名·關鍵字·牌義·牌陣名稱的語言:ko(預設)· en · ja · th

請求範例

{
  "spread": "past-present-future",
  "question": "올해 하반기에 이직해도 될까요?",
  "seed": "user-1042:2026-10-10"
}
curl -X POST https://api.hrum.ai/api/v1/partners/v1/tarot \
  -H "X-Partner-Api-Key: $HRUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"count": 1, "lang": "en", "reversed": false}'

回應範例(節錄 1 張牌)

{
  "success": true,
  "data": {
    "lang": "ko",
    "count": 3,
    "spread": { "type": "past-present-future", "name": "과거·현재·미래", "description": "시간 흐름을 따라가는 질문", "positions": ["과거", "현재", "미래"] },
    "reversedAllowed": true,
    "seed": "hrum-example-1",
    "cards": [
      {
        "position": 1,
        "positionLabel": "과거",
        "id": "wands_10",
        "name": "완드의 10",
        "nameEn": "Ten of Wands",
        "arcana": "wands",
        "reversed": true,
        "keywords": ["내려놓기", "위임", "해방"],
        "meaning": "무거운 짐을 마침내 내려놓거나 도움을 받기 시작하는 시기.",
        "imageUrl": "https://console.hrum.ai/tarot/cards/v2/wands_10.webp"
      }
    ],
    "cardBackUrl": "https://console.hrum.ai/tarot/cards/v2/back.webp",
    "question": "올해 하반기에 이직해도 될까요?",
    "costPoints": 20
  }
}

價格

Waite 原典依據 kb

開放後回應會附上 kb。針對每張抽出的牌,從 A. E. Waite《The Pictorial Key to the Tarot》(1910 年,公共領域)原文中,以規則 ID(R-TAROT-*)與原文引用回傳該牌的正位·逆位牌義。上方的 meaning·keywords 維持不變,只會多加 kb,價格相同。

{
  "method": "celtic-cross",
  "seed": "user-1042:2026-10-11"
}

錯誤代碼

除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
404tarot_not_enabled帳號尚未開通此功能
404tarot_kb_not_enabled傳送了 method,但原典依據尚未開放
402INSUFFICIENT_BALANCE餘額不足

count·spread·method 必須正好傳送其中一個。傳送兩個以上或都沒傳時回傳通用 400。

本命盤 API(西洋占星) 停止販售

停止販售 — 請改用占星全覽(/astrology)。以相同的出生輸入,每次 ₩50 即可一次取得 10 顆天體·宮位·相位,以及預先寫好的解讀段落。已串接的 /natal-chart 呼叫仍可正常運作,但不建議用於新的串接。

POST /api/v1/partners/v1/natal-chart

以出生年月日時計算西洋占星的本命盤(太陽·月亮·水星·金星·火星·木星·土星 7 顆天體位置 + 上升星座)。不包含天王星·海王星·冥王星。以西洋占星的回歸黃道為準,而非節氣。

請求參數

參數 型別 必填 說明
birthDate string O 出生日期 YYYY-MM-DD(國曆)。僅接受實際存在的日期(2 月 30 日等會被拒絕)
birthTime string 出生時刻 HH:mm(24 小時制)。省略 birthTimePrecision 時視為 exact,並以此時刻計算(2026-10-17 起)。若不使用時刻,請不要傳送 birthTime 或傳送 birthTimePrecision: "unknown"
gender string 性別("male" | "female")。僅為相容性而接受,不用於計算
birthLatitude number 緯度 -90~90(與經度一起用於計算上升星座)
birthLongitude number 經度 -180~180
birthTimezoneOffset number UTC 時差(分鐘),預設值:540(KST)
birthTimePrecision string "exact" | "approximate"(以時辰為單位) | "unknown"。省略時若有 birthTime 則為 exact,沒有則為 unknown(以正午計算)
readings boolean 為 true 時回應會附上 readings(行星品位·相位的解讀段落)。另加 ₩20。帳號尚未開通時回傳 404 natal_readings_not_enabled(不計費)
lang string readings 段落的語言 — ko(預設)· en · ja · th

回應欄位

欄位 型別 說明
sun object 太陽位置 { body, sign(韓文), signEn, element(韓文:불·흙·공기·물=火·土·風·水), degreeInSign, eclipticLongitude }
moon object 月亮位置
mercury object 水星位置
venus object 金星位置
mars object 火星位置
jupiter object 木星位置
saturn object 土星位置
ascendant object|null 上升星座。有出生時刻與座標,且 birthTimePrecision 為 exact(含省略)或 approximate 時才會計算,其他情況為 null
ascendantReason string 上升星座為 null 的原因(僅在有時附上,例:時刻精確度為 unknown 或沒有座標)
ascendantHourBasis boolean 以 approximate(以時辰為單位)時刻計算的上升星座時為 true — 請標示為「以時辰為準」
ascendantEstimate object|null approximate 時 ±60 分鐘範圍內的上升星座推估。window = { startLocal, endLocal, switchLocal, beforeSign, afterSign }(switchLocal 是範圍內星座改變的時刻,不改變則為 null)
moonSignUncertain boolean 僅在時刻不詳(unknown)時附上 — 當天內月亮星座改變時為 true(以正午為準的月亮星座不確定)
coordsBasis string|null 計算上升星座所用的位置:"coords"(傳送的座標)或 null(沒有座標·時刻不詳)
engineVersion string 計算版本。目前為 "natal-2" — 表示結果可能與沒有此欄位的舊回應不同(見下方 2026-10-17 變更)
readings object 僅在 readings: true 時。dignities(位於本垣·擢升·失勢·落陷的行星解讀)· aspects(最精確的相位最多 2 個,deviation = 偏離正相位的度數)· lang · costWon(附加費用)· missingSections(因尚無解讀文字而缺少的段落數,0 表示全部都有 — 即使缺少一部分,附加費用也相同)· version(解讀詞典的版本標示,值相同即文字相同 — 供比對用)

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/natal-chart \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "birthDate": "1990-05-15",
    "birthTime": "12:00",
    "birthLatitude": 37.5665,
    "birthLongitude": 126.978,
    "birthTimezoneOffset": 540,
    "birthTimePrecision": "exact"
  }'

回應範例

{
  "success": true,
  "data": {
    "sun": {
      "body": "Sun",
      "sign": "황소자리",
      "signEn": "Taurus",
      "element": "흙",
      "degreeInSign": 24.03,
      "eclipticLongitude": 54.0343
    },
    "moon": { "body": "Moon", "sign": "염소자리", "signEn": "Capricorn", "element": "흙", ... },
    "mercury": { "body": "Mercury", "sign": "황소자리", "signEn": "Taurus", ... },
    "venus": { "body": "Venus", "sign": "양자리", "signEn": "Aries", "element": "불", ... },
    "mars": { ... },
    "jupiter": { ... },
    "saturn": { ... },
    "ascendant": {
      "body": "Ascendant",
      "sign": "사자자리",
      "signEn": "Leo",
      "element": "불",
      "degreeInSign": 23.13,
      "eclipticLongitude": 143.1256
    },
    "coordsBasis": "coords",
    "engineVersion": "natal-2"
  }
}

上述範例請求:{"birthDate": "1990-05-15", "birthTime": "12:00", "birthLatitude": 37.5665, "birthLongitude": 126.978, "birthTimezoneOffset": 540, "birthTimePrecision": "exact"}(實際引擎輸出節錄)。

解讀段落(readings: true)

針對行星品位(本垣·擢升·失勢·落陷)與最精確的 2 個相位,附上預先寫好的解讀段落。與 INTA – Life is Timing 應用程式萬年曆畫面的段落相同。以下為實際引擎輸出(1990-09-04 14:30,首爾座標,exact)。

{
  "success": true,
  "data": {
    "sun": { ... }, "moon": { ... }, ...,
    "readings": {
      "dignities": [
        { "key": "Me_dom", "lang": "ko",
          "text": "수성이 본궁인 쌍둥이자리나 처녀자리에 있으면 정보를 모으고 분류해 말로 옮기는 기능이 막힘없이 또렷하게 드러나요. 생각이 많아질 때 하나를 골라 끝까지 파고들면 그 명료함이 실제 성과로 이어져요." },
        { "key": "Sa_dom", "lang": "ko",
          "text": "토성이 본궁인 염소자리나 물병자리에 있으면 책임을 지고 구조를 세워 반복 훈련으로 숙련을 쌓는 기능이 막힘없이 또렷하게 드러나요. 기준이 지나치게 굳어질 때 쉬어 갈 틈을 일정에 남겨 두면 그 인내가 성숙하게 쓰여요." }
      ],
      "aspects": [
        { "key": "Me_Sa_tr", "deviation": 0.04, "lang": "ko",
          "text": "수성과 토성의 트라인은 절제와 의지를 생각에 더해, 서두르지 않고 앞을 내다보며 구조를 짜는 데 힘이 실려요. 변화가 필요한 순간에 익숙한 방식만 고집할 수 있으니 새 방법도 한 번 시험해 보세요." },
        { "key": "Mo_Ma_sq", "deviation": 1.03, "lang": "ko",
          "text": "달과 화성이 스퀘어를 이루면 감정이 올라오는 순간 욱하거나 규칙에 반발하는 쪽으로 기울 수 있어요. 화가 난 뒤 반응을 한 템포 늦추는 연습을 하면 그 뜨거움이 지켜야 할 것을 지키는 힘으로 바뀌어요." }
      ],
      "lang": "ko",
      "costWon": 20
    }
  }
}
  • 出生時間不詳時(沒有 birthTime 或 birthTimePrecision: "unknown"),月亮的位置變動範圍大,因此不列入相位計算。
  • 沒有請求語言文字的段落會以韓文回傳,該段落的 lang 為 ko。
  • 無法載入解讀段落時回傳 503 natal_readings_unavailable(不計費)。

注意事項

錯誤代碼

除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
404natal_readings_not_enabledreadings: true 但解讀段落尚未開通
503natal_readings_unavailable無法載入解讀段落
402(無)餘額少於呼叫價格 — 此 API 在呼叫前不檢查餘額,因此會回傳沒有代碼的 402

占星全覽 API

如同萬年曆,一次呼叫即回傳全部占星計算。預設為完整本命盤(太陽~冥王星 10 顆天體 · 月交點 · 4 個軸點 · 宮位(預設 Placidus)· 相位 · 品位),在請求中加上區塊時,行運 + 次限推運(timing)與雙人合盤比較(partner)也會一併放在同一個回應中。只取用需要的部分即可。不使用 LLM。除了數值與規則鍵(features)之外,HRUM 預先寫好的解讀段落(readings)一律附上,不另收費。與 INTA 使用相同的共用占星引擎,天體位置已與 NASA/JPL Horizons·Swiss Ephemeris 的基準值比對驗證(行星誤差 0.005° 以內)。解讀參數(容許度·相位種類·品位表)全部來自古典原典的規則,原典之間有分歧的值(行運·推運容許度)不設預設值,由您自行選擇(見下方「預設值與必須自行選擇的值」)。

POST /api/v1/partners/v1/astrology

出生輸入與本命盤 API相同(birthDate · birthTime · birthTimePrecision · birthLatitude · birthLongitude · birthTimezoneOffset,預設 540 = KST,自動反映韓國夏令時間·1954~61 年 UTC+8:30)。省略 birthTimePrecision 時為 unknown(以正午為準)。

參數型別必填說明
houseSystemsstring[]從 placidus · whole_sign · equal · porphyry 中選擇。省略時為 ["placidus"]。出生地位於極圈內(緯度約 66.56° 以上,angles.polar)時,會以 Porphyry 取代 Placidus 計算,並在結果附上 "fallbackFrom": "placidus"(直接指定 Placidus 時也相同)
minorAspectsboolean納入十二分之一相(30°)·半四分相(45°)·八分之三相(135°)·十二分之五相(150°)(本命盤·合盤比較)。預設 false — 僅 5 種主要相位
orbsstring本命盤·合盤比較的容許度表:leo1928(預設 — 合相·對分相 日–月 12°、日/月–行星 10°、行星之間 8°,四分相·三分相 8°,六分相 7°,半四分相·八分之三相 4°,十二分之一相·十二分之五相 2°)· heindel1919(主要相位一律 6°,較保守)
nodestring規則鍵中的 Nn(北交點)·Sn(南交點 = 北交點 + 180°)所依據的交點:mean(預設,平均交點)· true(真實交點)。適用於 features 的 node_sign Nn_…·Sn_… 與交點合相鍵(Mo_Nn_cj·Nn_Asc_cj 等)。MNn_…·TNn_… 鍵不論此值為何都會兩者皆回傳
langstringsignName(星座名稱)的語言 — ko(預設)· en · ja · th
timingobject傳送時會計算行運 + 次限推運,並放入回應的 timing。見下表
partnerobject對方的出生輸入(與上方相同的欄位,lang 除外)。傳送時會將兩人之間的相位·星座關係放入回應的 synastry。若有對方的出生時刻與座標(birthLatitude·birthLongitude),也會計算對方的上升點(Asc)·天頂(MC)並納入交叉相位

timing 區塊內容:

參數型別必填說明
orbDegreesnumberO行運→本命、推運→本命相位的容許度(度)0.5~10。所有天體組合使用相同的值(僅 5 種主要相位)
atstring要查看的時間點。YYYY-MM-DD(= 當天 00:00 UTC)或附上時差的日期時間(2026-10-11T09:00:00+09:00、...Z)。沒有時差的日期時間回傳 400。省略時為現在
progressionsboolean計算次限推運(預設 true)
yearLengthstring將經過時間換算為「人生第幾年」時使用的一年長度:tropical(365.24219 日,預設)· julian(365.25 日)

請求範例 1 — 預設(僅本命盤)

{
  "birthDate": "1990-05-15",
  "birthTime": "14:30",
  "birthTimePrecision": "exact",
  "birthLatitude": 37.5665,
  "birthLongitude": 126.978,
  "houseSystems": ["placidus", "whole_sign"]
}
curl -X POST https://api.hrum.ai/api/v1/partners/v1/astrology \
  -H "X-Partner-Api-Key: $HRUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"birthDate": "1990-05-15", "birthTime": "14:30", "birthTimePrecision": "exact", "birthLatitude": 37.5665, "birthLongitude": 126.978, "minorAspects": true, "lang": "en"}'

回應範例 1(節錄,實際引擎輸出)

{
  "success": true,
  "data": {
    "natal": {
      "utc": "1990-05-15T05:30:00.000Z",
      "timePrecision": "exact",
      "timeKnown": true,
      "zodiac": "tropical",
      "lang": "ko",
      "bodies": [
        { "id": "Sun", "longitude": 54.1347, "sign": "Taurus", "signKey": "tau", "signName": "황소자리", "degreeInSign": 24.1347, "speed": 0.9643, "retrograde": false, "dignities": [], "house": { "placidus": 9, "whole_sign": 9 } },
        { "id": "Moon", "longitude": 293.8244, "sign": "Capricorn", "signKey": "cap", "signName": "염소자리", "degreeInSign": 23.8244, "speed": 12.2943, "retrograde": false, "dignities": ["det"], "house": { "placidus": 4, "whole_sign": 5 } },
        ...
      ],
      "nodes": [
        { "id": "MeanNode", "longitude": 311.3535, "sign": "Aquarius", "signName": "물병자리", "speed": -0.0529,
          "south": { "longitude": 131.3535, "sign": "Leo", "signName": "사자자리", ... } },
        { "id": "TrueNode", ... }
      ],
      "angles": { "asc": 173.5996, "mc": 82.8067, "dsc": 353.5996, "ic": 262.8067,
        "ascSign": { "sign": "Virgo", "signName": "처녀자리", ... }, "mcSign": { ... }, "dscSign": { ... }, "icSign": { ... }, "polar": false },
      "anglesOmitted": null,
      "houseSystems": ["placidus", "whole_sign"],
      "houses": {
        "placidus": { "cusps": [173.5996, 199.6989, 229.8749, ...], "bodies": { "Sun": 9, "Moon": 4, "Jupiter": 10, ... } },
        "whole_sign": { "cusps": [150, 180, 210, ...], "bodies": { "Sun": 9, "Moon": 5, ... } }
      },
      "housesExcluded": [],
      "orbs": "leo1928",
      "minorAspects": false,
      "aspects": [
        { "a": "Jupiter", "b": "Uranus", "type": "opposition", "code": "op", "key": "Ju_Ur_op", "separation": 179.6986, "orb": 0.3014, "orbLimit": 8, "strength": "exact", "applying": false, "outOfSign": false },
        { "a": "Sun", "b": "Moon", "type": "trine", "code": "tr", "key": "Su_Mo_tr", "orb": 0.3104, "orbLimit": 8, "strength": "exact", "applying": true, "outOfSign": false },
        ...
      ],
      "dignities": { "Sun": [], "Moon": ["det"], "Mercury": [], "Venus": ["det"], "Mars": [], "Jupiter": ["exa"], "Saturn": ["dom"] },
      "moonSignUncertain": false,
      "features": [
        { "type": "planet_sign", "key": "Su_tau" },
        { "type": "dignity", "key": "Mo_det" },
        { "type": "planet_retrograde", "key": "Me_rx" },
        { "type": "planet_house", "key": "Su_h9", "system": "placidus" },
        { "type": "aspect", "key": "Su_Mo_tr", "strength": "exact", "applying": true, "orb": 0.31 },
        { "type": "meta", "key": "time_known" },
        ...
      ]
    },
    "readings": {
      "dignities": [
        { "key": "Mo_det", "text": "달이 염소자리에서 손상 자리에 있으면 감정을 바로 내보이기보다 책임과 일의 질서 속에서 조심스럽게 다루는 경향이 있어요. ...", "lang": "ko" },
        { "key": "Ve_det", ... }, { "key": "Ju_exa", ... }, { "key": "Sa_dom", ... }
      ],
      "aspects": [
        { "key": "Su_Mo_tr", "text": "태양과 달의 트라인은 의지와 정서가 같은 곳을 바라봐, 스스로 길을 내며 생활 전반을 고르게 꾸려 가는 힘이 실려요. ...", "lang": "ko", "deviation": 0.31 },
        { "key": "Su_Sa_tr", ... }, { "key": "Mo_Sa_cj", ... }, ...
      ],
      "lang": "ko"
    },
    "readingsUnavailable": false,
    "costPoints": 50
  }
}

沒有傳送 timing·partner 時,回應中完全沒有 timing·synastry 鍵。

請求範例 2 — 含 timing(行運 + 次限推運)

{
  "birthDate": "1990-05-15",
  "birthTime": "14:30",
  "birthTimePrecision": "exact",
  "birthLatitude": 37.5665,
  "birthLongitude": 126.978,
  "houseSystems": ["whole_sign"],
  "timing": { "at": "2026-10-11T09:00:00+09:00", "orbDegrees": 3, "yearLength": "tropical" }
}
curl -X POST https://api.hrum.ai/api/v1/partners/v1/astrology \
  -H "X-Partner-Api-Key: $HRUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"birthDate": "1990-05-15", "timing": {"orbDegrees": 2, "progressions": false}}'

回應範例 2(節錄,natal 與範例 1 形式相同)

{
  "success": true,
  "data": {
    "natal": { ... },
    "timing": {
      "at": "2026-10-11T00:00:00.000Z",
      "orbDegrees": 3,
      "natalPoints": ["Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "Asc", "MC"],
      "transits": {
        "bodies": [ { "id": "Sun", "longitude": 197.6966, "sign": "Libra", "signName": "천칭자리", "speed": 0.9889, "retrograde": false, ... }, ... ],
        "aspects": [
          { "a": "Mars", "b": "Mercury", "type": "square", "key": "tMa_nMe_sq", "orb": 0.6358, "orbLimit": 3, "strength": "exact", "applying": true, "outOfSign": false },
          ...
        ]
      },
      "progressions": {
        "yearLength": "tropical",
        "yearLengthDays": 365.24219,
        "ageYears": 36.4081,
        "instant": "1990-06-20T15:17:39.048Z",
        "bodies": [ { "id": "Sun", "longitude": 89.0352, "sign": "Gemini", "signName": "쌍둥이자리", ... }, ... ],
        "aspects": [
          { "a": "Uranus", "b": "Mercury", "type": "trine", "key": "pUr_nMe_tr", "orb": 0.0862, "orbLimit": 3, "strength": "exact", "applying": false, "outOfSign": false },
          ...
        ]
      },
      "features": [
        { "type": "transit", "key": "tMa_nMe_sq", "strength": "exact", "applying": true, "orb": 0.64 },
        { "type": "progressed", "key": "pUr_nMe_tr", "strength": "exact", "applying": false, "orb": 0.09 },
        ...
      ]
    },
    "readings": { ... }, "readingsUnavailable": false,
    "costPoints": 50
  }
}

請求範例 3 — 含 partner(合盤比較)

{
  "birthDate": "1990-05-15",
  "birthTime": "14:30",
  "birthTimePrecision": "exact",
  "birthLatitude": 37.5665,
  "birthLongitude": 126.978,
  "houseSystems": ["whole_sign"],
  "partner": { "birthDate": "1992-11-03", "birthTime": "08:10", "birthTimePrecision": "exact", "birthLatitude": 35.1796, "birthLongitude": 129.0756 }
}
curl -X POST https://api.hrum.ai/api/v1/partners/v1/astrology \
  -H "X-Partner-Api-Key: $HRUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"birthDate": "1990-05-15", "birthTime": "14:30", "birthTimePrecision": "exact", "partner": {"birthDate": "1992-11-03"}}'

回應範例 3(節錄,natal 與範例 1 形式相同)

{
  "success": true,
  "data": {
    "natal": { ... },
    "synastry": {
      "partner": {
        "utc": "1992-11-02T23:10:00.000Z",
        "timePrecision": "exact",
        "timeKnown": true,
        "moonSignUncertain": false,
        "bodies": [ { "id": "Sun", "longitude": 220.7903, "sign": "Scorpio", "signName": "전갈자리", "speed": 1.0016, "retrograde": false, "dignities": [], ... }, ... ],
        "angles": { "asc": 252.31, "mc": 175.86, "ascSign": { "sign": "Sagittarius", "signName": "사수자리", ... }, "mcSign": { "sign": "Virgo", "signName": "처녀자리", ... } },
        "anglesOmitted": null
      },
      "orbs": "leo1928",
      "minorAspects": false,
      "aspects": [
        { "a": "Moon", "b": "Mars", "type": "opposition", "code": "op", "key": "aMo_bMa_op", "orb": 0.2993, "orbLimit": 10, "strength": "exact", "applying": null, "outOfSign": false },
        { "a": "Neptune", "b": "Uranus", "type": "conjunction", "code": "cj", "key": "aNe_bUr_cj", "orb": 0.3898, "orbLimit": 8, "strength": "exact", "applying": null, "outOfSign": false },
        ...
      ],
      "features": [
        { "type": "syn_aspect", "key": "aMo_bMa_op", "strength": "exact", "orb": 0.3 },
        { "type": "syn_aspect", "key": "aNe_bUr_cj", "strength": "exact", "orb": 0.39 },
        { "type": "astro_syn", "key": "Su_Mo_se" },
        { "type": "syn_sign", "key": "aAsc_bAsc_es" },
        ...
      ]
    },
    "readings": { ... }, "readingsUnavailable": false,
    "costPoints": 50
  }
}

預設值與必須自行選擇的值

不提供的項目

價格

錯誤代碼

除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
404astrology_not_enabled帳號尚未開通此功能
400at_before_birthtiming.at 早於出生時刻(開啟推運計算時)
402(無)餘額少於呼叫價格 — 此 API 在呼叫前不檢查餘額,因此會回傳沒有代碼的 402

運勢走勢 API

以一個人的八字計算大運·流年·流月疊加在命盤(原局)上的走勢,並以供圖表使用的數值與關係清單回傳。一次一人,不使用 LLM。縱軸的值是「疊加運勢干支後的日干側分數」— 在命盤強弱總分上,加上每個運勢干支依與命盤相同的逐字計分表(生扶·剋洩·藏干·通根)所評的分數,並截斷在 ±100 的值,並不衡量運勢的好壞(R-SAJU-UN-034)。身強·中和·身弱的名稱沿用命盤本身的判定,不會因運勢而重新標示。

價格:每次 ₩50(與萬年曆相同,擴大範圍或加上流月也是相同價格)。400 等失敗回應不計費。

所有數值皆由與 INTA 相同的共用八字引擎產生。出生時刻以韓國標準時的歷史時鐘時間(1954~61 年 UTC+8:30,自動反映夏令時間)讀取並與交節時刻比較,因此不論伺服器時區為何,結果都相同。

出生地(2026-10-15 新增,saju-flow-5):接受與萬年曆 API相同的欄位(birthLatitude·birthLongitude·country·birthTimePrecision),並以相同方式進行真太陽時校正。出生時刻接近時柱·日柱·交節的邊界時,校正會改變命盤的干支,因此請將傳給萬年曆的位置原樣也傳給運勢走勢,兩邊的結果才會使用同一個命盤。不傳送位置時,以與不帶位置呼叫萬年曆時相同的預設處理(目前為不校正)計算,並在回應的 assumedLocation 告知該預設值。

POST /api/v1/partners/v1/saju-flow

參數型別必填說明
birthDatestringOYYYY-MM-DD(1900~2100)。以 calendar 為準的日期
birthTimestring | nullHH:mm。沒有時為時柱不詳 — 以六個字計算,hourKnown: false
calendarstringOsolar · lunar(農曆會換算為國曆後計算)
isLeapMonthboolean農曆閏月(預設 false)
genderstring | nullmale · female。沒有時不含大運層(daeun: [],daeunIndex: null)
timezonestring僅接受 Asia/Seoul
birthLatitude · birthLongitudenumber出生地座標(必須兩者皆傳)。與萬年曆 API相同的欄位·相同的規則 — 以經度進行真太陽時校正,運勢走勢也繪製在萬年曆回傳的校正後命盤上。只傳其中一個時回傳 400 INVALID_LOCATION。不傳送時依循萬年曆的預設處理(目前為不校正),並以 assumedLocation 告知
countrystring出生國家的 2 字母代碼。不帶座標傳送 KR·JP·TH 時,以該國的代表經度校正(與萬年曆相同)
birthTimePrecisionstringexact · approximate · estimated · unknown。僅在 exact 時校正(傳送位置時預設為 exact)。傳送 exact 以外的值時,不做真太陽時校正。韓國夏令時間期間出生者,與萬年曆相同,減去 1 小時以標準時讀取(2026-10-16)
rangeobjectO{ "fromYear", "toYear" } 流年範圍(國曆年份,最多 101 年)。建議一次取得出生年 ~ 出生年+100,再於畫面上擷取使用
monthsOfYearinteger | null要計算流月 12 格的八字年份(當年立春起至隔年立春前)。省略時為目前(韓國時間)所屬的八字年份 — 1 月 1 日~立春前為前一年。null 時不含流月層(months: [])
langstringko · en · ja · th。回應值是與語言無關的代碼(干支的韓文讀音·五行·關係名稱),因此目前結果都相同。完整清單請見有效值 > 與語言無關的代碼值。

請求範例

{
  "birthDate": "1990-05-15",
  "birthTime": "14:30",
  "calendar": "solar",
  "gender": "male",
  "timezone": "Asia/Seoul",
  "range": { "fromYear": 1990, "toYear": 2090 },
  "monthsOfYear": 2026
}
curl -X POST https://api.hrum.ai/api/v1/partners/v1/saju-flow \
  -H "X-Partner-Api-Key: $HRUM_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: chart-123:flow:2026" \
  -d '{"birthDate": "1990-05-15", "birthTime": "14:30", "calendar": "solar", "gender": "male", "timezone": "Asia/Seoul", "range": {"fromYear": 1990, "toYear": 2090}, "monthsOfYear": 2026}'

回應範例(節錄,實際引擎輸出)

{
  "success": true,
  "data": {
    "engineVersion": "saju-flow-6",
    "kbVersion": "2026.10.11-7",
    "hourKnown": true,
    "natalAmbiguous": null,
    "natal": {
      "score": -37, "result": "중화", "level": "약약",
      "breakdown": { "season": -30, "support": 36, "control": -28, "hidden": -5, "root": 5 },
      "primaryYongshin": "토",
      "shin": { "yongshin": "토", "huishin": "화", "gishin": "목", "gushin": "수", "hanshin": "금" },
      "ruleIds": ["R-SAJU-STR-001", "R-SAJU-STR-018", "R-SAJU-STR-019", "R-SAJU-YONG-170"]
    },
    "daeun": [
      { "startYear": 1997, "endYear": 2006, "startAge": 7,
        "chars": [
          { "pos": "stem", "char": "임", "hanja": "壬", "ohaeng": "수", "sipsin": "식신", "shinRole": "gushin",
            "share": { "support": 0, "control": -8, "hidden": 0, "root": 0, "total": -8 } },
          { "pos": "branch", "char": "오", "hanja": "午", "ohaeng": "화", "sipsin": "정관", "shinRole": "huishin",
            "share": { "support": 0, "control": -10, "hidden": -5, "root": 0, "total": -15 } }
        ],
        "delta": -23, "line": { "value": -60, "clamped": false },
        "relations": [
          { "type": "자형", "from": "daeun", "with": "yearBranch", "a": "오", "b": "오", "ruleId": "R-SAJU-REL-044", "decisionRuleId": "R-SAJU-UN-036" },
          { "type": "육합", "from": "daeun", "with": "hourBranch", "a": "오", "b": "미", "ruleId": "R-SAJU-REL-015", "decisionRuleId": null }
        ],
        "triples": [], "hapPulim": [ ... ] },
      ...
    ],
    "years": [
      { "year": 2026, "daeunIndex": 2,
        "chars": [ { "pos": "stem", "char": "병", "hanja": "丙", ... "share": { ..., "total": -10 } },
                   { "pos": "branch", "char": "오", "hanja": "午", ... "share": { ..., "total": -15 } } ],
        "delta": -25, "line": { "value": -33, "clamped": false },
        "relations": [
          { "type": "천간합", "from": "seun", "with": "monthStem", "a": "병", "b": "신", "ruleId": "R-SAJU-REL-003", "decisionRuleId": null },
          ...
        ],
        "withDaeun": [], "triples": [],
        "hapPulim": [
          { "kind": "existing", "domain": "jiji", "pair": ["오", "미"], "status": "broken_by_dong",
            "reasonCode": "branch_hap_broken", "params": { "incoming": "오", "origin": "seun" },
            "triggeredBy": { "origin": "seun", "value": "오" },
            "reasonFallback": "동기 오(seun) 도래 → 합반 깨짐" },
          { "kind": "new", "domain": "cheongan", "pair": ["병", "신"], "chartValue": "신", "incomingValue": "병", "incomingOrigin": "seun",
            "reasonCode": "new_stem_hap", "params": { "incoming": "병", "origin": "seun", "partner": "신" },
            "reasonFallback": "병(seun) + 원국 신 → 새 천간 합 형성" },
          ...
        ],
        "ipchunNote": false },
      ...
    ],
    "months": [
      { "index": 1, "startsAt": "2026-02-04T04:55:00+09:00",
        "chars": [ { "pos": "stem", "char": "경", ... }, { "pos": "branch", "char": "인", ... } ],
        "delta": 4,
        "relations": [ { "type": "반합", "from": "wolun", "with": "yearBranch", "a": "인", "b": "오", "ruleId": "R-SAJU-REL-024", "decisionRuleId": "R-SAJU-UN-035" }, ... ] },
      ...
    ],
    "compatInputs": {
      "primaryYongshin": "토",
      "surfaceElementCounts": { "목": 0, "화": 2, "토": 2, "금": 3, "수": 1 },
      "surfaceAbsent": ["목"],
      "hourKnown": true,
      "ruleIds": ["R-SAJU-COMPAT-008", "R-SAJU-COMPAT-009", "R-SAJU-COMPAT-010"]
    },
    "caveats": ["R-SAJU-UN-028", "R-SAJU-PRAC-026", "R-SAJU-UN-034"],
    "birthBeforeIpchun": false,
    "assumedLocation": { "correction": "none" },
    "costPoints": 0
  }
}

欄位閱讀方式

價格

錯誤代碼

除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:

HTTP代碼發生時機
404saju_flow_not_enabled帳號尚未開通此功能
400INVALID_DATEbirthDate 格式錯誤或不存在的日期
400INVALID_LUNAR_DATE不存在的農曆日期
400INVALID_RANGEtoYear 早於 fromYear,或超過 101 年
400INVALID_TIMEbirthTime 不是 HH:mm 格式
400INVALID_LOCATIONbirthLatitude·birthLongitude 只傳送其中一個
409saju_flow_correction_unsupported傳送了位置,但校正後的命盤·大運數無法與萬年曆完全一致地套用到運勢走勢的罕見出生情況(實測約 0.1% — 校正跨越午夜而使大運數改變、時刻不詳但正午校正跨越交節等)。不會編造其他值,而是拒絕(不計費)。此類出生請以相同位置使用萬年曆 API
402(無)餘額少於呼叫價格 — 此 API 在呼叫前不檢查餘額,因此會回傳沒有代碼的 402

合盤 API

根據兩人的八字計算合盤。一次呼叫即回傳八字合盤(日柱 60×60 合盤表、依用途的分數與 6 軸、天干/地支關係、八字五行互補、十神、交叉神煞)、親密合盤符號表(參考文獻(1995)男女日柱表的符號與等級)、星座合盤(太陽、月亮、上升星座 3 層 + 依用途的行星,星座合盤段落最多 2 段)、生肖合盤(兩個生肖地支的關係與等級),並一併提供將五種分數依用途權重合併的綜合分數(headerBreakdown)。自 2026-10-16 起,也會回傳依位置彙整兩個命盤(原局)之間合、沖、刑、害、破等關係的關係表(relations)及其分數(p2Score)。與 INTA 應用程式合盤畫面使用相同引擎,相同輸入永遠得到相同結果。

INTA 應用程式畫面上的代表分數(大數字)= headerBreakdown.average(下方回應範例中為 62)。saju.score.total(範例中為 59)只平均日柱表與八字,是 HRUM 自有的分數,因此與畫面上的數字不同。

與 INTA 應用程式結果畫面 6 軸圖相同的值是 saju.iljuAxes(saju.axes 是依用途重新計算的另一組值)。知道出生時間的人,須如建議呼叫一併傳送 personXCountry + personXBirthTimePrecision: "exact",才會以與 INTA 應用程式相同的八字(真太陽時校正)計算。

POST /api/v1/partners/v1/compat

根據兩人的八字分析合盤。

請求參數

參數 類型 必填 說明
personABirthDate string O A 的出生日期(YYYY-MM-DD,預設為國曆。personACalendar: "lunar" 時為農曆)
personABirthTime string A 的出生時間(HH:MM,選填)
personAGender string A 的性別("male"/"female",也接受 "남"/"여"(男/女),選填)
personBBirthDate string O B 的出生日期(YYYY-MM-DD,預設為國曆。personBCalendar: "lunar" 時為農曆)
personBBirthTime string B 的出生時間(HH:MM,選填)
personBGender string B 的性別("male"/"female",也接受 "남"/"여"(男/女),選填)
purpose string 合盤用途 — yeonae_attraction(戀愛,預設)、marriage_stability(婚姻)、friendship(友情)、family_bond(家人)、coworker_cooperation(同事)、business_partnership(事業)。分數、6 軸、關係類型、關係描述、星座優先行星、綜合分數權重會依用途調整。其他值回傳 400 INVALID_PURPOSE(不計費)
lang string 文字語言 — ko(預設)、en、ja、th。categoryNarrative、astroReadings、astroSynastry 文字、classic1995 等級、tti 會以此語言回傳。saju 區塊中 relationRatings 的 key、meetingKeywords、authority、full8、conflict 與 dayFlow.summary、yearFlow.years[].summary、dictionary 也依此語言。自 2026-10-13 起,saju 基本欄位(highlights、relation、tenGods、elements、bestFor/weakFor、pattern.name)也以此語言回傳。mbti、yearFlow.years[].a/b 目前僅支援韓文
personABirthTimePrecision / personBBirthTimePrecision string 時間精確度 — exact、approximate(以時辰為單位)、estimated、unknown。星座合盤:預設為有時間則 exact,無時間則 unknown。八字:真太陽時校正只在 exact 時套用;省略此欄位但傳送座標或 personXCountry 時視為 exact(與萬年曆 API 規則相同)
personABirthLatitude / personABirthLongitude
personBBirthLatitude / personBBirthLongitude
number 出生地座標(兩者需一起傳送)。同時用於上升星座計算與八字真太陽時校正(自 2026-10-11 起八字也套用)。若無座標,上升星座以 personXCountry 推估,若也沒有,則以 lang 對應國家的代表座標推估(ko→韓國、ja→日本、th→泰國/en 則省略上升星座)
personABirthTimezoneOffset / personBBirthTimezoneOffset number UTC 偏移(分鐘),預設 540(KST)。與座標一起傳送時,八字校正的標準子午線也以此值決定(省略時採用經度最接近的時區)。若同時傳送 personXBirthTimezone,以後者為優先
personABirthTimezone / personBBirthTimezone string 出生地時區(IANA,例:"America/New_York",選填,2026-10-14)。以與萬年曆 API 的 timezone 相同的規則計算八字,相同出生資訊的四柱會與萬年曆 API 一致 — 若非首爾,則以該時區(含夏令時間)讀取節氣交接時刻;與座標一起傳送時,以扣除夏令時間的標準偏移作為校正基準。優先於 personXBirthTimezoneOffset,星座合盤星盤則以該時區在出生當時實際使用的時刻(含夏令時間)繪製。省略時與以往計算方式完全相同(出生時間視為韓國時間)。無法辨識的名稱會比照省略時計算,並在回應中附上 warnings(UNKNOWN_TIMEZONE,每人一筆)
personACalendar · personAIsLeapMonth
personBCalendar · personBIsLeapMonth
string · boolean "lunar" 時將出生日期視為農曆,轉換為國曆後計算(預設 "solar")。IsLeapMonth: true 表示閏月;若該年沒有該閏月,或該農曆日期不存在,回傳 400 INVALID_LUNAR_DATE(不計費)。若有人以農曆傳送,回應會附上 lunarInput({a, b},格式與萬年曆 API 相同)
personACountry / personBCountry string 出生國家 2 碼代碼。不傳座標而傳送 KR·JP·TH 時,以該國代表經度校正八字時刻(其他國家不校正)。星座合盤的上升星座推估也改用此國家而非 lang
personAZaSiRule / personBZaSiRule string 子時(23 點後)的日柱:"traditional"(預設,用隔天日柱)、"yajaSi"(夜子時,用當天日柱、位置校正後 23 點時段的時柱天干以隔天日干為準,自 2026-10-20 起)
details boolean 預設 false。true 時附上 saju.full8(八字詳細分析)、saju.conflict({pattern, tip} 衝突模式與建議)、saju.relationScores(天干、地支關係分數)、最上層 dictionary({a, b} 兩人的日柱辭典 — 干支基本值(五行、陰陽、藏干、十二長生)、性格關鍵字、一句話摘要)。dictionary.a/b 的 id(ilju_경진)、name_kr 是與語言無關的日柱代碼值(韓文)。en、th 的干支單字、十二長生等為羅馬拼音(Gap、Mogyok),ja 為漢字。saju.full8 的 personA/B.elementDistribution、sipsinCount、combinedElementBalance.distribution 物件鍵是與語言無關的韓文代碼值(목、비견 等)。完整清單請見有效值 > 與語言無關的代碼值。
flow boolean 預設 false。true 時附上 yearFlow(基準年 ±2 年,5 個年份的兩人運勢)與 dayFlow(基準日 ±7 天,15 天的兩人運勢)
date string flow 的基準日 YYYY-MM-DD(1900-2100)。預設:韓國時間今天
currentYear number yearFlow 的基準年(1900~2100)。預設:date 的年份
personAMbti / personBMbti string MBTI 4 個字母(例:ENFP,不分大小寫)。兩人都傳送時,附上最上層 mbti(MBTI 合盤,韓文)

details、flow、MBTI 選項不另收費(每次呼叫仍為 ₩20)。

對知道出生時間的人,請一併傳送出生國家與 "exact"。真太陽時校正會與 INTA 應用程式一致,即使出生時間接近時辰交界,日柱、分數也會與應用程式相同。

{
  "personABirthDate": "1990-09-04", "personABirthTime": "14:30", "personAGender": "male",
  "personACountry": "KR", "personABirthTimePrecision": "exact",
  "personBBirthDate": "1992-02-20", "personBBirthTime": "10:15", "personBGender": "female",
  "personBCountry": "KR", "personBBirthTimePrecision": "exact",
  "purpose": "yeonae_attraction", "details": true
}

回應範例

以下是實際引擎輸出(A 男 1990-09-04 14:30,B 女 1992-02-20 10:15,戀愛,無座標)。2026-10-10 新增的必定包含欄位(saju.relationRatings、saju.meetingKeywords、saju.authority、tti.conflictFrame)在此範例中省略 — 請見下方選項範例。這兩人即使以建議呼叫(KR + exact)傳送,值也相同。

{
  "success": true,
  "data": {
    "personABirthDate": "1990-09-04", "personABirthTime": "14:30", "personAGender": "male",
    "personBBirthDate": "1992-02-20", "personBBirthTime": "10:15", "personBGender": "female",
    "tti": {
      "userTti": "말", "partnerTti": "원숭이",
      "relation": { "type": null, "detail": null, "relations": [] },
      "tier": "흉"
    },
    "saju": {
      "purpose": "yeonae_attraction",
      "hourKnown": { "a": true, "b": true },
      "personA": { "ilju": "임신" },
      "personB": { "ilju": "병인" },
      "score": { "total": 59, "grade": "맞춰 가면 좋아요",
                 "breakdown": { "ilju": 53, "authority": 65, "eightChar": 65 } },
      "axes": { "attraction": 25, "stability": 59, "growth": 58,
                "communication": 24, "passion": 74, "longevity": 65 },
      "pattern": { "name": "폭발형",
                   "description": "에너지가 크게 부딪히는 뜨거운 관계예요. 감정이 커질 때 잠시 쉬어 가는 규칙이 도움이 돼요." },
      "relation": { "summary": "천간충 + 인신충",
                    "stem": { "type": "천간충", "detail": "병임충" },
                    "branches": [ { "type": "지지충", "detail": "인신충" } ] },
      "elements": { "basis": "eight", "aLacks": [], "bProvidesToA": [], "bLacks": ["토"], "aProvidesToB": ["토"] },
      "tenGods": { "aView": "편재", "bView": "편관(칠살)" },
      "bestFor": ["단기 끌림"],
      "weakFor": ["결혼·동거"],
      "highlights": [ "상대의 시지에 나의 천을귀인 (사) 발현 — 상대가 나의 해결사" ],
      "iljuAxes": { "attraction": 45, "stability": 16, "growth": 88,
                    "communication": 60, "passion": 70, "longevity": 50 }
    },
    "categoryNarrative": {
      "category": "romantic", "purpose": "yeonae_attraction", "lang": "ko",
      "text": "상대 쪽의 즉각적인 열정과 나 쪽의 자유로운 흐름은 불과 물처럼 정면으로 맞부딪혀서, 처음 만났을 때의 팽팽한 긴장감이 곧 끌림이 되기 쉬워요. 짧고 뜨거운 설렘이 큰 관계라, 감정이 치솟는 날엔 하루쯤 식힐 틈을 두면 더 즐겁게 만날 수 있어요.",
      "styleVersion": "v2"
    },
    "costPoints": 20,
    "classic1995": {
      "symbol": "××", "grade": "대흉", "score": 50,
      "ttiRelation": { "type": null, "detail": null, "relations": [] },
      "conflictFrame": false
    },
    "relations": [
      { "positions": ["month", "month"], "kind": "chung", "tier": "heavyClash",
        "ruleIds": ["R-SAJU-REL-034", "R-SAJU-COMPAT-106", "R-SAJU-COMPAT-112"], "chars": ["申", "寅"] },
      { "positions": ["day", "day"], "kind": "chung", "tier": "heavyClash",
        "ruleIds": ["R-SAJU-REL-034", "R-SAJU-COMPAT-106", "R-SAJU-COMPAT-112"], "chars": ["申", "寅"] },
      { "positions": ["day", "day"], "kind": "stemChung", "tier": "clash",
        "ruleIds": ["R-SAJU-REL-008", "R-SAJU-COMPAT-110"], "chars": ["壬", "丙"] },
      { "positions": ["year", "year"], "kind": "napeumSaeng", "tier": "gather",
        "ruleIds": ["R-SAJU-BASE-037", "R-SAJU-COMPAT-111"], "chars": ["庚午", "壬申"] },
      { "positions": ["chart", "chart"], "kind": "banghap", "tier": "gather",
        "ruleIds": ["R-SAJU-REL-021", "R-SAJU-COMPAT-104"], "chars": ["巳", "午", "未"] }
    ],
    "p2Score": 57,
    "astroSynastry": {
      "self": {
        "sun": { "signEn": "Virgo", "element": "earth", "modality": "mutable" },
        "moon": { "signEn": "Pisces", "element": "water", "modality": "mutable", "uncertain": false },
        "ascendant": { "signEn": "Sagittarius", "element": "fire", "modality": "mutable", "uncertain": false, "countryBasis": true },
        "venus": { "signEn": "Leo", ... }, "mars": { "signEn": "Gemini", ... },
        "mercury": { ... }, "jupiter": { ... }, "saturn": { ... }
      },
      "partner": { "sun": { "signEn": "Pisces", ... }, "moon": { "signEn": "Virgo", ... }, ... },
      "layers": [
        { "key": "sun", "relation": "opposite", "selfSign": "Virgo", "partnerSign": "Pisces",
          "textKey": "compat.astro.relation.opposite",
          "text": "충 — 정반대라 방향은 다르지만 서로를 끌어당길 수 있어요" },
        { "key": "moon", "relation": "opposite", "selfSign": "Pisces", "partnerSign": "Virgo",
          "textKey": "compat.astro.relation.opposite",
          "text": "충 — 정반대라 방향은 다르지만 서로를 끌어당길 수 있어요" },
        { "key": "ascendant", "relation": "neutral", "selfSign": "Sagittarius", "partnerSign": "Taurus",
          "textKey": "compat.astro.relation.neutral",
          "text": "뚜렷한 결 없이 각자의 스타일을 존중하면 되는 조합이에요" }
      ],
      "purposeBodies": [
        { "body": "venus", "relation": "opposite", "selfSign": "Leo", "partnerSign": "Aquarius",
          "textKey": "compat.astro.relation.opposite",
          "text": "충 — 정반대라 방향은 다르지만 서로를 끌어당길 수 있어요" },
        { "body": "mars", "relation": "same_element", "selfSign": "Gemini", "partnerSign": "Aquarius",
          "textKey": "compat.astro.relation.same_element",
          "text": "같은 원소 — 서로의 방식을 바로 알아볼 만큼 편안할 수 있어요" }
      ],
      "caveats": ["compat.astro.caveat.ascendantCountryBasis"],
      "caveatTexts": ["상승궁은 출생 도시가 없어 국가 대표 좌표로 추정했어요"],
      "score": 64
    },
    "astroReadings": [
      { "key": "Su_Mo_ss", "lang": "ko",
        "text": "한쪽의 태양과 다른 쪽의 달이 같은 별자리에 놓이면, 한 사람이 향하는 방향을 다른 사람의 마음이 낯설지 않게 알아보는 깊은 공명이 생기기 쉬워요. 닮은 만큼 같은 그림자도 함께 커질 수 있으니 서로의 빈틈을 웃으며 짚어 주면 좋아요." },
      { "key": "Ve_Ma_op", "lang": "ko",
        "text": "한쪽의 금성과 다른 쪽의 화성이 정반대 별자리에 놓이면, 서로에게 없는 매력을 알아보며 끌리는 보완의 흐름이 생기기 쉬워요. 원하는 속도와 표현 방식이 반대로 기울 수 있으니 서로의 선을 말로 정해 두면 그 끌림이 편안하게 이어져요." }
    ],
    "headerBreakdown": {
      "sixAxis": 55, "authority": 65, "full8": 65, "classic": 57, "natal": 64,
      "average": 62, "purpose": "yeonae_attraction",
      "weights": { "sixAxis": 0.2, "authority": 0.3, "full8": 0.2, "classic": 0.1, "natal": 0.2 }
    },
    "engineVersion": "compat-2",
    "lang": "ko"
  }
}

關係類型(relations[].kind)

kind含義tier
yukhap地支六合 — 兩個地支配對相合gather
banhap地支半合 — 三合三字中的兩字listOnly
samhap三合 — 合併兩個命盤後三字聚集,形成一個五行局gather
banghap方合 — 合併兩個命盤後同一季節的三個地支聚集gather
chung地支沖 — 正面相撞heavyClash
hyung地支刑clash
hae地支害clash
pa地支破(寅亥、巳申 這兩組是六合,因此為 listOnly)clash
wonjin怨嗔listOnly
stemHap日干之間的天干合gather
stemChung日干之間的天干沖clash
napeumSaeng年柱納音五行相生gather
napeumBihwa年柱納音五行相同gather
napeumGeuk年柱納音五行相剋clash

相同的 kind 一律對應相同的 tier(只有破的兩組例外)。之後可能新增 kind,請讓程式略過不認得的值。

選項範例(details · flow · MBTI)

實際引擎輸出節錄。請求:

{
  "personABirthDate": "1990-05-15", "personABirthTime": "12:00", "personAGender": "male",
  "personBBirthDate": "1992-08-20", "personBBirthTime": "09:00", "personBGender": "female",
  "details": true, "flow": true, "date": "2026-10-10",
  "personAMbti": "ENFP", "personBMbti": "ISTJ"
}
{
  "success": true,
  "data": {
    "tti": { "userTti": "말", "partnerTti": "원숭이", ..., "tier": "흉", "conflictFrame": false },
    "saju": {
      "personA": { "ilju": "경진" }, "personB": { "ilju": "무진" },
      "score": { "total": 56, "grade": "맞춰 가면 좋아요", ... },
      ...,
      "relationRatings": [
        { "key": "연애", "stars": 3 }, { "key": "결혼·동거", "stars": 3 }, { "key": "친구", "stars": 4 },
        { "key": "사업 파트너", "stars": 3 }, { "key": "장기 관계", "stars": 3 }
      ],
      "meetingKeywords": ["괴강", "우직", "일반적 관계"],
      "authority": {
        "finalScore": 51, "grade": "주의", "gradeTier": "caution",
        "pattern": "자형 (자기 갈등 외부화)",
        "summary": "주의 · 자형 (자기 갈등 외부화) · 익숙한 결의 만남. 안락함 위에 자극을 어떻게 만들지가 핵심.",
        "levels": { "L1": { "raw": 0, "norm": 0 }, "L2": { "raw": 5, "norm": 14.3, "type": "동계절 (봄)" },
                    "L3": { "raw": 17, "norm": 56.7 }, "L4": { "raw": -17, "norm": -42.5 } },
        "factors": { "l1": [], "l2Tone": "...", "l3": [ ... ], "l4": ["자형(진진) — 자기 파괴 패턴", ...] },
        "flags": { "cheonHapJiHap": false, "dualChung": false },
        "climateBalance": "동계절 (봄)"
      },
      "conflict": {
        "pattern": "경은 무를 편인으로 인식. 일방향적 관계 성격.",
        "tip": "'괴강'과 '우직'은 서로 다른 결이에요. 같은 사건도 다르게 해석한다는 걸 인정하고, 서로의 관점을 한 번씩 빌려보세요."
      },
      "relationScores": { "stem": { "type": "편인", "category": "neutral", "score": 55 },
                          "branches": [ { "type": "자형", "score": -40 } ] },
      "full8": { "personA": { ... }, "personB": { ... }, "iljuEvaluation": { ... }, ... }
    },
    ...,
    "dictionary": { "a": { "id": "ilju_경진", "name_kr": "경진", "name_hanja": "庚辰", ... }, "b": { ... } },
    "yearFlow": {
      "baseYear": 2026,
      "years": [
        { "year": 2024, "score": 77, "tier": "great", "a": { ... }, "b": { ... },
          "summary": "두 분 모두 흐름이 좋아 같이 시작하기 좋은 해." },
        ...
      ]
    },
    "dayFlow": {
      "baseDate": "2026-10-10",
      "days": [
        { "date": "2026-10-03", "a": -89, "b": -40, "combined": -60, "tier": "hard", "isBaseDate": false },
        ...,
        { "date": "2026-10-10", "a": -9, "b": 27, "combined": 9, "tier": "neutral", "isBaseDate": true },
        ...
      ],
      "golden": [],
      "hard": [ { "date": "2026-10-03", "combined": -60 }, ... ],
      "summary": "3번 같이 가라앉는 날이 있어. 그날은 큰 결정·약속 미루자."
    },
    "mbti": { "id": "mbti_ENFP_ISTJ", "mbti_a": "ENFP", "mbti_b": "ISTJ",
              "socionics_relation": "Duality(이중관계)", "scores": { ..., "total": 64 }, ... }
  }
}

注意事項

錯誤代碼

除了共通錯誤(401、400 內文檢查、402、429、503 等)之外,此 API 會出現的代碼:

HTTP代碼時機
400INVALID_BIRTH_YEAR兩人中有人的出生年份不在 1900~2100 範圍內
400INVALID_LUNAR_DATE不存在的農曆日期
400COMPAT_UNAVAILABLE此日柱組合沒有合盤資料
402INSUFFICIENT_BALANCE餘額不足

請求範例請見上方選項範例與執行範例。

性格類型 API

提供以 MBTI 為基礎的性格測驗。支援免費精簡版(24 題)與進階版(93 題)。

GET /api/v1/partners/v1/personality-type/questions

查詢性格測驗題目。免費。

curl "https://api.hrum.ai/api/v1/partners/v1/personality-type/questions?tier=free" \
  -H "X-Partner-Api-Key: your-api-key"

請求參數

參數 類型 說明
tier string 測驗版本("free" 或 "premium",預設值:"free")

回應範例

{
  "success": true,
  "data": {
    "tier": "free",
    "count": 24,
    "questions": [
      {
        "id": "q_001",
        "text": "갑자기 생긴 모임에도 일단 가본다",
        "choices": [
          { "value": 1, "label": "전혀 그렇지 않다" },
          { "value": 2, "label": "그렇지 않다" },
          { "value": 3, "label": "보통이다" },
          { "value": 4, "label": "그렇다" },
          { "value": 5, "label": "매우 그렇다" }
        ]
      }
    ]
  }
}

POST /api/v1/partners/v1/personality-type

提交性格測驗的答案,分析性格類型。

curl -X POST https://api.hrum.ai/api/v1/partners/v1/personality-type \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "tier": "free",
    "answers": [
      { "questionId": "q_001", "answer": 4 },
      { "questionId": "q_002", "answer": 2 }
    ]
  }'

請求參數

參數 類型 必填 說明
answers array O 答案陣列 [{ "questionId": "q_001", "answer": 4 }, ...]。questionId 是題目查詢回應中的 id(格式 q_001),answer 為整數 1~5。premium 在四個軸(外向、內向/實感、直覺/思考、情感/判斷、感知)上每軸至少需要一個答案(否則回傳 400 personality_axis_unanswered)。為求結果準確,建議回答題目查詢取得的全部 93 題
tier string O "free" 或 "premium"

回應範例

{
  "success": true,
  "data": {
    "personalityType": "ENTJ",
    "typeLabel": "지휘관",
    "scores": {
      "extraversion": 72,
      "sensing": 45,
      "thinking": 68,
      "judging": 80
    },
    "tier": "premium",
    "costPoints": 10
  }
}

價格

錯誤代碼

除了共通錯誤(401、400 內文檢查、402、429、503 等)之外,此 API 會出現的代碼:

HTTP代碼時機
400(無)題目查詢 — tier 不是 free、premium/提交 — 不存在的 questionId
400personality_axis_unanswered提交 — premium 但有完全沒有答案的軸(axes 中列出空白的軸)
402INSUFFICIENT_BALANCE提交 — premium 但餘額不足

答案在 1~5 以外時為共通 400。以上皆不計費。

解讀資料庫(KB)API

僅對已申請的帳號開放的 API。未開放的帳號在三個路徑都會收到 404 kb_saju_explain_not_enabled(不計費)。如需使用,請透過支援洽詢。

將八字命盤中成立的關係(合、沖等)與結構(十神、藏干等)以規則卡與解說文字說明。不使用 LLM,相同輸入永遠得到相同結果。

POST /api/v1/partners/v1/kb/saju/explain

請求參數

參數類型必填說明
birthobjectO與萬年曆 API 請求內文相同的欄位(year、month、day、hour?、minute?、timezone、gender、calendar? …)。birth.lang 會被忽略。無法辨識 birth.timezone 時,回應會附上 warnings(field: "birth.timezone")
sectionsstring[]relations · structure · all。省略時為全部(依 relations → structure 順序)
levelstringL1(預設)· L3。沒有 L3 解說的項目以 L1 補上,並附上 fallbackLevel
langstring僅支援 ko
channelstringstable(預設,僅含已審核的解說)· preview(包含審核前的解說 — 僅限另外獲准的帳號,其他帳號回傳 403 KB_PREVIEW_NOT_ALLOWED)

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/kb/saju/explain \
  -H "X-Partner-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "birth": {
      "year": 1990, "month": 5, "day": 17, "hour": 14, "minute": 30,
      "timezone": "Asia/Seoul", "gender": "female"
    },
    "sections": ["relations"]
  }'

回應範例(節錄)

{
  "success": true,
  "data": {
    "kbVersion": "2026.10.09-3",
    "kbHash": "sha256:24b9a2d9...",
    "channel": "stable",
    "chart": {
      "pillars": {
        "year":  { "stem": "庚", "branch": "午" },
        "month": { "stem": "辛", "branch": "巳" },
        "day":   { "stem": "壬", "branch": "午" },
        "hour":  { "stem": "丁", "branch": "未" }
      },
      "timeUnknown": false
    },
    "sections": [
      {
        "id": "relations",
        "title": "...",
        "steps": [
          {
            "fact": { "type": "stem_pair", "a": "壬", "b": "丁", "posA": "day", "posB": "hour", "relation": "hap" },
            "factText": "일간 壬과 시간 丁은 천간합(天干合) 관계다.",
            "componentId": "saju:stem_pair:丁壬:hap",
            "rules": [
              { "id": "R-SAJU-REL-004", "kind": "definition", "status": "verified", "sourceCount": 2,
                "statement": "丁과 壬은 천간합 관계이고, 이 짝의 합화 오행은 목(木)이다." }
            ],
            "interp": {
              "meaning": { "text": "丁(정)과 壬(임)은 천간합으로 묶이는 짝이고, ...", "reviewed": false },
              "why": { ... },
              "pitfall": { ... }
            }
          }
        ],
        "absent": [
          { "type": "stem_pair", "a": "庚", "b": "辛", "posA": "year", "posB": "month",
            "note": "庚과 辛은 천간합·천간충 어느 것도 아니다." }
        ]
      }
    ],
    "unregistered": [],
    "pendingReview": []
  }
}

GET /api/v1/partners/v1/kb/rules/{id}

回傳單一規則卡與原典出處。免費。

curl https://api.hrum.ai/api/v1/partners/v1/kb/rules/R-SAJU-REL-004 \
  -H "X-Partner-Api-Key: your-api-key"
{
  "success": true,
  "data": {
    "id": "R-SAJU-REL-004",
    "kind": "definition",
    "statement": "丁과 壬은 천간합 관계이고, 이 짝의 합화 오행은 목(木)이다.",
    "status": "verified",
    "schools": [],
    "variantOf": null,
    "sources": [
      { "sourceId": "SRC-SMTH", "location": "『三命通會』 卷二 論十干化氣",
        "quote": "故丁與壬合 丁壬化木", "match": "EXACT", ... }
    ],
    "engineRef": "..."
  }
}

GET /api/v1/partners/v1/kb/release?domain=saju

回傳目前公開的解讀資料庫版本。免費。domain 省略時為 saju(例:saju · ziwei · astro · dream · tarot)。

curl "https://api.hrum.ai/api/v1/partners/v1/kb/release?domain=saju" \
  -H "X-Partner-Api-Key: your-api-key"
{
  "success": true,
  "data": {
    "version": "2026.10.09-3",
    "hash": "sha256:24b9a2d9...",
    "publishedAt": "2026-10-09T00:00:00.000Z",
    "channel": "stable",
    "counts": { "rules": 412, "interps": 1236 }
  }
}

上方數字為範例。若您會儲存結果,請在 hash 改變時重新取得。

錯誤代碼

除了共通錯誤之外:

HTTP代碼時機
404kb_saju_explain_not_enabled未申請的帳號(三個路徑共通)
400INVALID_LUNAR_DATE · INVALID_LOCATIONexplain — 不存在的農曆日期/只傳送了緯度、經度其中之一
403KB_PREVIEW_NOT_ALLOWEDexplain — 未獲准使用 channel: "preview" 的帳號(不計費)
400KB_DOMAIN_UNKNOWNrelease — 不支援的 domain
404KB_RULE_NOT_FOUNDrules — 不存在的規則 id
503KB_NOT_LOADED解讀資料庫版本尚未載入。請稍後再試

explain 只對成功的呼叫計費,失敗的呼叫記錄為 ₩0。

應用程式郵件寄送 API

讓上架到 RIDM Apps 的應用程式寄送註冊確認、訂單通知、密碼重設等交易、服務通知郵件的 API。只能以應用程式專用金鑰(HRUM_API_KEY,主控台 > 我的應用程式 > AI 連線)呼叫,以一般 API 金鑰呼叫會回傳 403 MAIL_APP_KEY_REQUIRED。應用程式容器封鎖了 SMTP 連接埠,請透過此 API 寄送郵件。

POST /api/v1/partners/v1/mail/send

請求參數

參數類型必填說明
tostring | string[]O收件人地址 1~10 個。不接受帶顯示名稱的地址(Name <address>)
subjectstringO主旨 1~200 字,不可換行
textstring△內文(純文字)。text 或 html 至少要有一個。最多 10 萬字
htmlstring△內文(HTML),最多 20 萬字。寄送前會整理:刪除 script、style、iframe、表單、事件屬性,連結只保留 http(s)、mailto、tel,圖片只保留 https。沒有 text 時,會從 HTML 產生純文字內文一併寄送
replyTostring接收回覆的地址。沒有則使用主控台中填寫的地址,若也沒有則不帶回覆地址寄送
attachmentsobject[]附件最多 3 個,合計最多 512KB。{ "filename", "contentType", "content" }(content 為 base64)。只接受 PDF、PNG、JPEG、GIF、WebP、TXT、CSV、ICS
kindstringtransactional(預設值)· notification。為 notification 時會附上一鍵取消訂閱標頭,並略過在該應用程式取消訂閱的地址(suppressed)

請求範例

curl -X POST https://api.hrum.ai/api/v1/partners/v1/mail/send \
  -H "Content-Type: application/json" \
  -H "X-Partner-Api-Key: $HRUM_API_KEY" \
  -d '{
    "to": "user@example.com",
    "subject": "Welcome aboard",
    "text": "Your sign-up is complete. Get started with the link below.",
    "html": "<p>Your sign-up is complete.</p><p><a href=\"https://myapp.ridm.ai\">Get started</a></p>"
  }'

回應範例

{
  "success": true,
  "data": {
    "requestId": "7f1c2a3e-…",
    "results": [ { "to": "user@example.com", "status": "sent", "messageId": "<…>" } ],
    "sent": 1,
    "chargedWon": 0
  }
}

status 為 sent(郵件伺服器已接收)· failed(未能寄送 — 不收費)· suppressed(退信、垃圾郵件檢舉的地址,或在該應用程式取消訂閱 notification 郵件的地址,因此略過)其中之一。

上限與價格

項目內容
每月內含封數包含在方案中(免費 100 封、Basic 1,000 封、Pro 3,000 封,以應用程式為單位,韓國時間每月 1 日重設)。內含部分不另收費
超過內含封數時免費方案會暫停到下個月 1 日。付費方案只有在主控台開啟額外寄送時,才會以每封 1 韓元(VAT 另計、含 VAT 1.1 韓元)繼續寄送。只有郵件伺服器已接收的郵件,會在寄出後立即從點數中扣除
每日上限每個應用程式預設 500 封(可在主控台設定 1~5,000 封)。韓國時間午夜重設
每分鐘上限每個應用程式每分鐘 30 封

錯誤

HTTPcode說明
400MAIL_INVALID請求有誤。reason 中會說明原因(invalid_recipient、too_many_recipients、subject_invalid、advertising_not_allowed、body_required、attachment_type_not_allowed、attachments_too_large 等)
402insufficient_credit點數不足以支付額外寄送的費用。不會寄出任何郵件
403MAIL_APP_KEY_REQUIRED以非應用程式專用金鑰的金鑰呼叫
403APP_NOT_ACTIVE金鑰所連結的應用程式未在運作中
402MAIL_OVERAGE_UNPAID未能扣除的額外郵件費用超過餘額。儲值後會扣除未付的費用並重新開放(內含封數內的寄送照常進行)
403MAIL_EMAIL_UNVERIFIED沒有已完成電子郵件驗證的主控台帳號
403MAIL_SUSPENDED超過垃圾郵件檢舉、退信標準,或營運者已暫停,因此此應用程式的郵件寄送已暫停
429MAIL_RATE_LIMITED超過每分鐘上限。請在 retryAfterSeconds 後再寄送
429MAIL_DAILY_CAP_EXCEEDED超過每日上限。韓國時間午夜重新開放
429MAIL_MONTHLY_LIMIT本月內含封數已用完(免費方案,或額外寄送已關閉)
503MAIL_UNAVAILABLE無法使用郵件伺服器。請稍後再試

為網頁元宇宙加上目前線上人數

在 Three.js 等網頁 3D 空間或一般網頁上顯示「目前 N 人在線」的免費功能。在主控台 > 線上人數 註冊網站後,即可取得公開網站金鑰(pk_presence_…)與一行指令碼。不需金鑰、登入,直接在瀏覽器中載入。

放入指令碼

將在主控台 > 線上人數 取得的指令碼放一行到頁面中,並在要顯示數字的位置加上 data-hrum-online。

<script src="https://hrum.ai/p/presence.js" data-key="pk_presence_YOUR_SITE_KEY" async></script>

<span data-hrum-online></span> online now

這樣就完成了。每個開啟頁面的分頁會立即傳送一次,之後每 30 秒傳送訊號,並將傳回的線上人數填入所有加上 data-hrum-online 的元素。數字傳回之前為空白。

直接使用數字

指令碼會建立 window.HrumPresence。要在自己的畫面上繪製數字(3D 招牌、徽章等)時使用。

HrumPresence.onChange(function (online) {
  // online: current visitor count (integer)
  myScene.setVisitorCount(online);
});

HrumPresence.online;    // last number received, null if none yet
HrumPresence.refresh(); // send once more now and update the number
HrumPresence.stop();    // stop counting and send a leave signal

onChange 只在數字改變時呼叫。若在已取得數字後才註冊,會當場呼叫一次。若以 async 放入指令碼,HrumPresence 可能尚未存在,請等它出現後再註冊。

function whenPresence(fn) {
  if (window.HrumPresence) return fn(window.HrumPresence);
  setTimeout(function () { whenPresence(fn); }, 200);
}
whenPresence(function (p) { p.onChange(function (n) { myScene.setVisitorCount(n); }); });

Three.js 範例

hrum.ai/samples/presence-three/?key=pk_presence_… — 在以 Three.js 製作的小房間裡,加上「目前 ○ 人」徽章與 3D 招牌的範例。招牌與桌子周圍的人形,會以 onChange 收到的數字繪製。可直接拿頁面原始碼作為起點。放到自己的網站時,請使用已將該網站地址加入允許地址的金鑰。

在頁面外只讀取數字

儀表板、機器人等需要在頁面外只取得數字時,請使用查詢 API。不會傳送訊號,因此不會增加線上人數。

curl https://api.hrum.ai/api/v1/partners/v1/presence/sites/pk_presence_…/online
# {"success":true,"data":{"online":42,"source":"beacon","updatedAt":"2026-10-31T01:23:45.000Z"}}

數字沒有顯示時,請確認目前頁面的地址(origin)是否在允許的地址中。允許的地址只接受 https,且連接埠也必須相同。

端點

方法 · 路徑說明
POST /api/v1/partners/v1/presence/beat傳送訊號。內文 { "siteKey", "sid" }(JSON,text/plain 或 application/json,最多 1KB)。sid 是每個分頁產生的隨機值(16~64 字,英文、數字、_、-)。Origin 不在允許的地址中時回傳 403。回應 { online }
POST /api/v1/partners/v1/presence/leave關閉分頁時(navigator.sendBeacon)立即移除該分頁。內文與 beat 相同,回應為 204
GET /api/v1/partners/v1/presence/sites/{siteKey}/online查詢目前線上人數 { online, source, updatedAt }。source 為 server(伺服器傳送的值)或 beacon(指令碼訊號統計)。任何頁面都可呼叫(CORS *),快取 10 秒。已作廢的金鑰回傳 404
POST /api/v1/partners/v1/presence/sites/{siteKey}/count從伺服器傳送數字(見下方)。需要伺服器金鑰,每分鐘一次。也可一併傳送各房間人數 rooms
GET /api/v1/partners/v1/presence/sites/{siteKey}/rooms房間伺服器挑選要進入的房間時使用的各房間人數(見下方)。需要伺服器金鑰,不公開
GET /api/v1/partners/v1/presence/directory同意 Metamoa 分享的網站清單(名稱、地址、線上人數)。快取 30 秒

回應範例

// POST /presence/beat
{ "success": true, "data": { "online": 12 } }

// GET /presence/sites/pk_presence_…/online
{ "success": true, "data": { "online": 12, "source": "beacon", "updatedAt": "2026-10-31T09:00:00.000Z" } }

// GET /presence/directory
{ "success": true, "data": [ { "label": "우주 광장", "siteUrl": "https://example.com/world", "online": 12 } ] }

從伺服器傳送數字

若您的伺服器(遊戲伺服器、即時伺服器等)已經知道線上人數,可以由伺服器直接傳送數字。在主控台 > 線上人數 中為每個網站核發伺服器金鑰(sk_presence_…)。伺服器金鑰只在核發時顯示一次,請存放在伺服器的環境變數中,不要放進頁面、瀏覽器程式碼。重新核發後,先前的伺服器金鑰會立即停用。

各房間人數(選用)

若伺服器將房間(頻道、執行個體)分開使用,可在同一個 count 內文中一併傳送各房間人數與容量。房間伺服器決定要把新使用者放進哪個房間時,以 GET …/rooms 重新讀取。各房間數字只能以伺服器金鑰讀取,不會出現在公開查詢(online、directory)與 presence.js 中。整體線上人數照現在的方式以 online 另外傳送(不以房間合計代替計算)。

POST /api/v1/partners/v1/presence/sites/pk_presence_…/count
X-Presence-Secret: sk_presence_…
Content-Type: application/json

{
  "online": 98,
  "rooms": [
    { "id": "studio-1", "n": 30, "cap": 30 },
    { "id": "studio-2", "n": 28, "cap": 30 },
    { "id": "studio-3", "n": 40, "cap": 50 }
  ]
}

// 200
{ "success": true, "data": { "online": 98, "reportedAt": "2026-10-31T09:00:00.000Z" } }
GET /api/v1/partners/v1/presence/sites/pk_presence_…/rooms
Authorization: Bearer sk_presence_…

// 200
{ "success": true, "data": {
  "rooms": [
    { "id": "studio-1", "n": 30, "cap": 30, "free": 0 },
    { "id": "studio-2", "n": 28, "cap": 30, "free": 2 },
    { "id": "studio-3", "n": 40, "cap": 50, "free": 10 }
  ],
  "reportedAt": "2026-10-31T09:00:00.000Z"
} }

伺服器金鑰只放在伺服器上。若將 sk_presence_… 放進瀏覽器程式碼、應用程式、公開儲存庫,任何人都能更改線上人數。請放在環境變數或機密儲存空間,若已外洩,請立即在主控台 > 線上人數 重新核發。

請每分鐘傳送一次。5 分鐘內沒有新值時,會回到指令碼訊號統計。也可以與瀏覽器指令碼一起使用,此時頁面上的徽章會顯示伺服器傳送的數字。

curl

curl -X POST "https://api.hrum.ai/api/v1/partners/v1/presence/sites/pk_presence_…/count" \
  -H "Content-Type: application/json" \
  -H "X-Presence-Secret: $HRUM_PRESENCE_SECRET" \
  -d '{"online": 128}'
# {"success":true,"data":{"online":128,"reportedAt":"2026-10-31T01:23:45.000Z"}}

Node(WebSocket 伺服器)

// Node 18+ (built-in fetch), next to your `ws` server
setInterval(() => {
  fetch("https://api.hrum.ai/api/v1/partners/v1/presence/sites/pk_presence_…/count", {
    method: "POST",
    headers: { "Content-Type": "application/json", "X-Presence-Secret": process.env.HRUM_PRESENCE_SECRET },
    body: JSON.stringify({ online: wss.clients.size }),
  }).catch(() => {}); // a missed report is fine: the next one comes in 60 s
}, 60_000);

Cloudflare Workers (Durable Object)

// One Durable Object per room holds the WebSockets and reports their number every 60 s.
// wrangler secret put HRUM_PRESENCE_SECRET ; vars: HRUM_SITE_KEY = "pk_presence_…"
import { DurableObject } from "cloudflare:workers";

const API = "https://api.hrum.ai/api/v1/partners/v1/presence";

export class Room extends DurableObject {
  async fetch(request) {
    const [client, server] = Object.values(new WebSocketPair());
    this.ctx.acceptWebSocket(server);
    if (!(await this.ctx.storage.getAlarm())) await this.ctx.storage.setAlarm(Date.now() + 60_000);
    return new Response(null, { status: 101, webSocket: client });
  }

  async alarm() {
    const online = this.ctx.getWebSockets().length;
    await fetch(`${API}/sites/${this.env.HRUM_SITE_KEY}/count`, {
      method: "POST",
      headers: { "Content-Type": "application/json", "X-Presence-Secret": this.env.HRUM_PRESENCE_SECRET },
      body: JSON.stringify({ online }),
    }).catch(() => {});
    // keep reporting while anyone is connected; after the last one leaves, 0 was the final report
    if (online > 0) await this.ctx.storage.setAlarm(Date.now() + 60_000);
  }
}

Supabase(Realtime Presence)

Edge Function 會進入使用者 track() 的頻道,計算 presence 鍵的數量後傳送,並由 pg_cron 每分鐘呼叫。每次連線各有一個鍵,若要讓一個人只計算一次,請在使用者端以 config: { presence: { key: userId } } 建立頻道。

// supabase/functions/presence-count/index.ts
// supabase secrets set HRUM_PRESENCE_SECRET=sk_presence_… HRUM_SITE_KEY=pk_presence_…
import { createClient } from "jsr:@supabase/supabase-js@2";

const API = "https://api.hrum.ai/api/v1/partners/v1/presence";

Deno.serve(async () => {
  const supabase = createClient(Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!);
  const channel = supabase.channel("room-1"); // the channel name your clients use
  const online = await new Promise<number>((resolve) => {
    const count = () => resolve(Object.keys(channel.presenceState()).length);
    channel.on("presence", { event: "sync" }, count).subscribe();
    setTimeout(count, 5_000); // no sync within 5 s: report what is there
  });
  await supabase.removeChannel(channel);
  const res = await fetch(`${API}/sites/${Deno.env.get("HRUM_SITE_KEY")}/count`, {
    method: "POST",
    headers: { "Content-Type": "application/json", "X-Presence-Secret": Deno.env.get("HRUM_PRESENCE_SECRET")! },
    body: JSON.stringify({ online }),
  });
  return new Response(null, { status: res.ok ? 204 : 502 });
});
-- every minute (pg_cron + pg_net); project_url and service_role_key stored in Vault
select cron.schedule('hrum-presence-count', '* * * * *', $$
  select net.http_post(
    url := (select decrypted_secret from vault.decrypted_secrets where name = 'project_url') || '/functions/v1/presence-count',
    headers := jsonb_build_object('Authorization', 'Bearer ' ||
      (select decrypted_secret from vault.decrypted_secrets where name = 'service_role_key'))
  );
$$);

Metamoa 分享

在主控台開啟「顯示在 Metamoa 目錄」後,該網站的名稱、地址、目前線上人數會顯示在 Metamoa 等由 HRUM 營運的目錄中。網站地址與允許的地址不符時不會顯示。隨時可以關閉。

個人資料

錯誤

HTTPcode說明
400PRESENCE_BAD_REQUEST · INVALID_BODYsiteKey、sid 格式錯誤,或內文不是 JSON
401PRESENCE_SECRET_REQUIRED沒有伺服器金鑰或金鑰錯誤(包含以公開金鑰傳送的情況)— 僅限 count
403PRESENCE_ORIGIN_NOT_ALLOWED沒有 Origin 或不在允許的地址中
404PRESENCE_SITE_NOT_FOUND不存在的金鑰或已作廢的金鑰
413PAYLOAD_TOO_LARGE內文超過 1KB
429PRESENCE_RATE_LIMITED訊號過多,或在 1 分鐘內再次傳送 count(Retry-After)。請稍後再傳送

驗證 API

用於管理主控台帳號的驗證 API。

POST /api/v1/partners/v1/console/auth/login

以電子郵件與密碼登入。以社群帳號("provider": "google"、"apple",POST …/console/auth/google、/apple)新註冊,自 2026-10-17 起不再受理,會回傳 410 SOCIAL_SIGNUP_DISABLED。已用社群帳號註冊的使用者可照常登入。

請求(電子郵件)

curl -X POST https://api.hrum.ai/api/v1/partners/v1/console/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "email",
    "email": "[email protected]",
    "password": "your-password"
  }'

回應

{
  "success": true,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "id": "user-123",
      "email": "[email protected]",
      "displayName": "John Doe",
      "provider": "email"
    }
  }
}

user.provider 為 email · apple · google 其中之一。

POST /api/v1/partners/v1/console/auth/register

註冊新帳號。

請求

curl -X POST https://api.hrum.ai/api/v1/partners/v1/console/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "secure-password",
    "displayName": "John Doe",
    "agreements": { "terms": true, "privacy": true }
  }'

password 為 8~128 字,displayName(顯示名稱或公司名稱)為 2~50 字。agreements.terms、agreements.privacy 必須為 true(缺少或為 false 時回傳 400),agreements.aiTraining(boolean)為選填。agreements.marketing(boolean,選填)是同意接收新功能、優惠通知郵件。未傳送或為 false 時記錄為不同意。

回應

{
  "success": true,
  "data": {
    "message": "인증 메일을 발송했어요"  // "Verification email sent"
  }
}

POST /api/v1/partners/v1/console/auth/verify-email

完成電子郵件驗證。請一併傳送驗證郵件中的 token 與註冊時設定的密碼。

請求

curl -X POST https://api.hrum.ai/api/v1/partners/v1/console/auth/verify-email \
  -H "Content-Type: application/json" \
  -d '{
    "token": "token-from-verification-email",
    "password": "secure-password"
  }'

回應

{
  "success": true,
  "data": {
    "message": "이메일 인증이 완료되었어요"  // "Email verification complete"
  }
}

token 錯誤、已過期或密碼不符時回傳 400 EMAIL_VERIFY_FAILED。驗證郵件連結(GET /api/v1/partners/v1/console/auth/verify-email?token=…)不會進行驗證,只會 302 重新導向到 https://console.hrum.ai/verify-email.html?token=… — 在該頁面輸入密碼後,就會呼叫上方的 POST。

以 AI 管理主控台

Claude Code、Cursor、Codex 等 AI 程式開發工具可以代為處理主控台的工作。查詢由 AI 直接進行;核發金鑰、儲值連結、託管申請等會造成變更的工作,必須由人在主控台同意畫面按下「同意」才會進行。伺服器會拒絕沒有同意碼的寫入,因此沒有不經人同意就通過的途徑。唯一的例外是下方的 hosting_ops,只對核發時由人勾選的 token 開放。

主控台管理 token

  1. AI 帶著要做的事(做什麼、金額、對象)呼叫 POST /api/v1/partners/v1/console-ai/consents,取得 consentUrl 與 code。
  2. AI 將連結顯示給使用者(MCP 也可以用瀏覽器開啟)。
  3. 使用者在已登入主控台的狀態下開啟連結,會看到「AI 提出的請求」標示,以及請求內容原文(金額、對象、名稱)。確認後按下「同意」。付款也是之後在 Toss 付款視窗中由人親自完成。
  4. AI 以 GET /console-ai/consents/{code} 確認核准後,在寫入請求內文中放入 consentCode 繼續進行。

同意碼只能使用一次,10 分鐘後過期。請求內容的雜湊固定在同意碼上,因此同意後若更改金額或對象再傳送,會被拒絕(CONSENT_MISMATCH)。

第一個 token 因為還沒有 token,請以 {"action":"token_issue","payload":{"scopes":["keys"]}} 在不驗證的情況下請求。將回應中的 pollSecret 放入標頭 X-Consent-Poll-Secret 查詢狀態,核准後只有第一次查詢會回傳一次 token 值。同一回應中的 account.email 是核准的主控台帳號經遮蔽的電子郵件。若不是您的帳號,請在主控台作廢該 token。

curl -X POST https://api.hrum.ai/api/v1/partners/v1/console-ai/consents \
  -H "Authorization: Bearer $HRUM_CONSOLE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action":"credit_topup_link","payload":{"planKey":"credit_50000"}}'

# response data
{
  "code": "cc_…",
  "consentUrl": "https://console.hrum.ai/console-consent.html#c=cc_…",
  "expiresAt": "2026-10-16T06:10:00.000Z",
  "action": "credit_topup_link",
  "display": [
    { "label": "충전 상품", "value": "credit_50000" },
    { "label": "결제 금액(부가세 포함)", "value": "55,000원" }
  ]
}

# after the user agrees
curl -X POST https://api.hrum.ai/api/v1/partners/v1/console-ai/credit/topup-link \
  -H "Authorization: Bearer $HRUM_CONSOLE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"planKey":"credit_50000","consentCode":"cc_…"}'

端點

全部位於 /api/v1/partners/v1/console-ai 之下。

方法、路徑用途權限同意
POST /consents建立同意請求({action, payload})action 的權限(第一個 token 不需要)—
GET /consents/{code}同意狀態:pending · approved · denied · expired · usedread(第一個 token 用 poll secret)—
GET /me · GET /token我的帳號 · 此 token 的權限read—
GET /status入門檢查清單(API · 託管 · 付款狀態與下一步)read—
GET /keysAPI 金鑰清單(僅前綴)read—
GET /credit · GET /credit/transactions點數餘額 · 明細(offset, limit ≤ 100)read—
GET /usage各期間的呼叫、支出(from, to)read—
GET /hosting是否可申請託管、方案、應用程式狀態read—
GET /seller · GET /payouts賣家狀態(不含本人資料)· 撥款明細read—
POST /keys核發 API 金鑰({label?})keyskey_issue
POST /keys/{id}/rotate核發新金鑰 + 立即停用此金鑰keyskey_rotate
POST /keys/{id}/revoke作廢金鑰(無法復原)keyskey_revoke
POST /credit/topup-link儲值付款連結({planKey})creditcredit_topup_link
POST /credit/refund-preview計算可退款金額(不會提出申請)creditcredit_refund_preview
POST /hosting/apply申請託管({planKey, subdomain, recurringConsent?})hostinghosting_apply
POST /hosting/apps/{id}/cancel解約託管hostinghosting_cancel
POST /seller/apply-link賣家註冊畫面連結sellerseller_apply_link

寫入請求的內文,是與同意請求 payload 相同的值 + consentCode。新的 API 金鑰只會在該回應中顯示一次。

卡號與賣家本人資料不透過 AI 路徑接收。信用卡付款在 Toss 付款視窗、賣家本人資料、帳戶、條款同意則在主控台畫面中由人親自輸入。payload 中若有規定項目以外的值,會以 400 UNKNOWN_FIELD 拒絕。

錯誤代碼

代碼HTTP含義
MGMT_TOKEN_INVALID401沒有 token,或已過期、撤銷。請重新核發
MGMT_SCOPE_DENIED403此 token 沒有所需的寫入權限(scope 欄位)。請勾選該權限重新核發
ACCOUNT_SUSPENDED403已停權的帳號
CONSENT_REQUIRED400寫入請求中沒有 consentCode
CONSENT_PENDING409尚未由人同意
CONSENT_DENIED403已由人拒絕
CONSENT_EXPIRED410超過 10 分鐘,已過期
CONSENT_USED409已使用過的同意碼
CONSENT_MISMATCH409同意的內容(金額、對象)與目前的請求不同
CONSENT_NOT_FOUND404不存在的代碼,或其他帳號的代碼
INVALID_CONSENT_PAYLOAD400payload 值不正確(field 欄位)
UNKNOWN_FIELD400包含不透過 AI 路徑接收的項目
CONSENT_RATE_LIMITED429同意請求過多
MGMT_TOKEN_LIMIT409已有 10 個有效 token,無法再核發
NOT_AVAILABLE404尚未開放的選單

以 MCP 使用

安裝 HRUM MCP(@hrum/mcp 0.2.0)後,即可將上述流程直接當作工具使用。token、API 金鑰、poll secret 不會出現在模型(對話)中,只會儲存在這台電腦的設定資料夾與 .env.local。

claude mcp add hrum -- npx -y https://console.hrum.ai/mcp/hrum-mcp-0.3.6.tgz
工具用途
hrum_ai_connect · hrum_ai_connect_status建立管理 token 同意連結 → 核准後儲存 token(不顯示值)
hrum_status · hrum_keys_list · hrum_credit · hrum_credit_history · hrum_usage · hrum_hosting_status · hrum_seller_status · hrum_payouts_list查詢
hrum_consent_request · hrum_consent_status寫入同意請求 · 狀態確認
hrum_key_issue · hrum_key_rotate · hrum_key_revoke金鑰核發、重新核發(新金鑰只儲存在 .env.local)· 作廢
hrum_topup_link · hrum_refund_preview儲值連結 · 可退款金額
hrum_hosting_apply · hrum_hosting_cancel · hrum_seller_apply_link託管申請、解約 · 賣家註冊連結

查詢 API

查詢點數餘額與使用狀況的 API。標頭中必須包含 X-Partner-Api-Key。

GET /api/v1/partners/v1/credits/balance

查詢目前的點數餘額。

請求

curl -X GET https://api.hrum.ai/api/v1/partners/v1/credits/balance \
  -H "X-Partner-Api-Key: your-api-key"

回應

{
  "success": true,
  "data": {
    "balanceWon": 25000,
    "lastUpdated": "2026-10-09T05:12:30.000Z",
    "estimatedMonthEndBalance": 15000,
    "warningThreshold": 5000,
    "lowBalanceActive": false
  }
}

warningThreshold 因合作夥伴而異 — max(₩5,000, 最近付費儲值金額的 20%)。lowBalanceActive 表示餘額是否已低於此基準、處於低餘額警示狀態。沒有透過 API 儲值的端點 — 儲值請在主控台 > 付款 中進行。此 API 沒有專屬錯誤代碼 — 只會出現共通錯誤。

GET /api/v1/partners/v1/usage/logs?limit=50&offset=0

依最新順序查詢 API 呼叫紀錄。每個項目包含 id、timestamp、endpoint(簡稱,例:manseryeok)、statusCode、costWon、responseTimeMs(目前一律為 null),僅在適用時附上 idempotencyKey、model、endUserId、cachedTokens。

請求參數

參數 類型 說明
limit number 查詢筆數(預設:50,最多:200)
offset number 偏移量(預設:0)
endpoint string 以端點簡稱篩選(例:manseryeok)。all 或省略時為全部
dateFrom · dateTo string 期間(YYYY-MM-DD)。省略時不限制

請求

curl "https://api.hrum.ai/api/v1/partners/v1/usage/logs?limit=50&offset=0&endpoint=manseryeok" \
  -H "X-Partner-Api-Key: your-api-key"

回應

{
  "success": true,
  "data": {
    "logs": [
      {
        "id": "12345",
        "timestamp": "2026-08-10T14:30:00.000Z",
        "endpoint": "manseryeok",
        "statusCode": 200,
        "costWon": 50,
        "responseTimeMs": null,
        "idempotencyKey": "order-8812"
      }
    ],
    "total": 1234,
    "pagination": {
      "limit": 50,
      "offset": 0,
      "hasMore": true
    }
  }
}

GET /api/v1/partners/v1/usage/summary?dateFrom=2026-08-01&dateTo=2026-08-31

查詢各期間的用量統計。省略日期時為本月全部。dailyBreakdown 的日期以韓國時間(KST)為準。

請求參數

參數 類型 說明
dateFrom string 開始日期(YYYY-MM-DD)
dateTo string 結束日期(YYYY-MM-DD)

請求

curl "https://api.hrum.ai/api/v1/partners/v1/usage/summary?dateFrom=2026-08-01&dateTo=2026-08-31" \
  -H "X-Partner-Api-Key: your-api-key"

回應

{
  "success": true,
  "data": {
    "dateRange": { "from": "2026-08-01", "to": "2026-08-31" },
    "totalCalls": 1234,
    "totalCostWon": 6170,
    "byEndpoint": [
      {
        "endpoint": "manseryeok",
        "calls": 1234,
        "costWon": 6170,
        "percentOfTotal": 100
      }
    ],
    "dailyBreakdown": [
      {
        "date": "2026-08-10",
        "calls": 150,
        "costWon": 750
      }
    ]
  }
}

錯誤代碼(用量紀錄、摘要)

除了共通錯誤之外,日期不是 YYYY-MM-DD 格式,或 limit、offset 為負數時,會回傳不帶代碼的 400。查詢免費。

GET /api/v1/partners/v1/status/upstream

彙整並回傳 HRUM 使用的 AI 供應商(OpenAI · Google Gemini · Anthropic Claude)的公開狀態。不需要 API 金鑰、免費,快取 60 秒。服務狀態頁面使用此值。

curl https://api.hrum.ai/api/v1/partners/v1/status/upstream

{
  "success": true,
  "data": {
    "providers": [
      { "name": "OpenAI", "indicator": "none", "description": "All Systems Operational", "url": "https://status.openai.com", "checkedAt": "2026-10-12T03:00:00.000Z" },
      ...
    ],
    "checkedAt": "2026-10-12T03:00:00.000Z"
  }
}

indicator:none(正常)· minor · major · critical · unknown(無法讀取狀態)。此 API 沒有專屬錯誤代碼。

訪客體驗

不需登入即可體驗八字的免費 API。

POST /api/v1/partners/v1/playground/manseryeok

不需驗證即可計算萬年曆。訪客端點(萬年曆、本命盤)合計每個 IP 每月免費 5 次,超過時回傳 429 GUEST_QUOTA_EXCEEDED。

請求

curl -X POST https://api.hrum.ai/api/v1/partners/v1/playground/manseryeok \
  -H "Content-Type: application/json" \
  -d '{
    "year": 1990,
    "month": 1,
    "day": 15,
    "hour": 14,
    "minute": 30,
    "timezone": "Asia/Seoul",
    "gender": "male"
  }'

回應

data 中會包含與付費萬年曆 API 相同的命盤、分析欄位(wonkuk · ohaengBalance · yongshin · daeun · seun …),以及剩餘次數 guestRemaining。農曆(calendar · isLeapMonth)、位置校正(座標 · country)、zaSiRule、birthTimePrecision 與付費版同樣套用,以農曆輸入時會附上 lunarInput。由於是體驗版,不包含 lang 翻譯、glossary 以及 identity、ohaengDeficient。無法辨識 timezone 時,會與付費版同樣附上 warnings。

{
  "success": true,
  "data": {
    "wonkuk": {
      "year": { "stem": "기", "branch": "사", "stemHanja": "己", "branchHanja": "巳", ... },
      "month": { ... }, "day": { ... }, "hour": { ... }
    },
    "trueSolarTime": null,
    "ohaengBalance": { ... },
    "yongshin": "...",
    ...,
    "guestRemaining": 4
  }
}

超過上限(429)

{
  "success": false,
  "statusCode": 429,
  "code": "GUEST_QUOTA_EXCEEDED",
  "message": "게스트 체험 한도(월 5회)를 초과했어요. API 키를 발급받아 사용해주세요.",  // "Guest trial limit (5 per month) exceeded. Please get an API key."
  "timestamp": "..."
}

錯誤代碼

HTTP代碼時機
429GUEST_QUOTA_EXCEEDED同一 IP 本月超過 5 次(與本命盤訪客合計)
400INVALID_LUNAR_DATE · INVALID_LOCATION不存在的農曆日期/只傳送了緯度、經度其中之一。這種情況也會扣除 1 次
400(無)內文檢查失敗(與共通錯誤相同)

POST /api/v1/partners/v1/playground/natal-chart

不需驗證即可計算本命盤。請求內文與付費 /natal-chart 相同,回應也是在相同的星盤上附上 guestRemaining。不提供解讀段落(readings)。上限與萬年曆訪客合計(每個 IP 每月 5 次)。

curl -X POST https://api.hrum.ai/api/v1/partners/v1/playground/natal-chart \
  -H "Content-Type: application/json" \
  -d '{ "birthDate": "1990-05-15", "birthTime": "12:00", "birthLatitude": 37.5665, "birthLongitude": 126.978, "birthTimezoneOffset": 540 }'

{
  "success": true,
  "data": {
    "sun": { ... },
    "moon": { ... },
    ...,
    "guestRemaining": 3
  }
}

錯誤:超過上限時回傳 429 GUEST_QUOTA_EXCEEDED,其他與共通錯誤相同。

有效值

天干(Cheongan)

갑(甲)、을(乙)、병(丙)、정(丁)、무(戊)、기(己)、경(庚)、신(辛)、임(壬)、계(癸)

地支(Jiji)

자(子)、축(丑)、인(寅)、묘(卯)、진(辰)、사(巳)、오(午)、미(未)、신(申)、유(酉)、술(戌)、해(亥)

五行(Ohaeng)

목(木)、화(火)、토(土)、금(金)、수(水)

與語言無關的代碼值

以下欄位即使傳送 lang,也會以韓文代碼值原樣輸出。這些不是畫面顯示用的名稱,而是用於分支、查詢的值。要顯示的名稱,請使用同一回應中的翻譯欄位(primaryLabel · signEn 等)或萬年曆 glossary: true 術語表。值的種類為上述天干、地支、五行與十神(비견 比肩 · 겁재 劫財 · 식신 食神 · 상관 傷官 · 편재 偏財 · 정재 正財 · 편관 偏官 · 정관 正官 · 편인 偏印 · 정인 正印)。

直言度(candor)

t、f(預設)— 不區分大小寫。舊值 blunt 會正規化為 t,balanced · gentle 會正規化為 f。其他值回傳 400(直言度(暫定名稱))

錯誤代碼

所有 API 都以相同方式回傳下方的共通錯誤。各 API 章節的錯誤表只列出該 API 專屬的代碼。請求依下列順序檢查,在前面的步驟被擋下時,後面的步驟不會執行。

  1. 安全規則 — 在抵達 API 伺服器之前過濾被封鎖的 User-Agent(403,內文為 HTML,error 1010)。此時尚未檢查 API 金鑰,因此是 403 而非 401
  2. 服務保護上限 — 來自同一 IP 的所有請求的每分鐘上限(429,無 code)
  3. API 金鑰 — 確認 X-Partner-Api-Key(401)
  4. 功能是否開放 — 帳號未開放的功能(404 *_not_enabled)
  5. 請求限制 — 在主控台設定的每秒、每日限制(429 RATE_LIMIT_EXCEEDED)
  6. 內文檢查 — 欄位名稱、類型、範圍(400)
  7. 餘額、計算、呼叫 — 餘額不足(402)、各 API 的輸入錯誤、外部模型錯誤

共通錯誤

HTTP 代碼 時機 計費
400(無)內文檢查失敗 — 傳送了表中沒有的欄位,或類型、範圍錯誤。message 為字串陣列無
401(無)缺少 X-Partner-Api-Key、金鑰錯誤、已作廢的金鑰、停用的帳號無
402INSUFFICIENT_BALANCE點數餘額不足。串流回應會在 event: error 中帶有相同的 code 與 status無
402(無)扣款當下餘額不足(呼叫前不檢查餘額的 API,或呼叫期間其他請求用掉餘額的情況)。message 中帶有所需金額與剩餘餘額無
403(內文為 HTML)安全規則封鎖(error 1010)— 預設 User-Agent 被封鎖的 HTTP 用戶端。請見 Quickstart 中的 User-Agent 注意事項無
404*_not_enabled帳號未開放的功能(例:ziwei_not_enabled、dream_not_enabled)無
404(無)不存在的路徑。內文 message 只有 "Not Found"無
429(無)超過服務保護上限(每個 API 金鑰每分鐘 300 次等)。沒有 Retry-After — 最多 1 分鐘後再試無
429RATE_LIMIT_EXCEEDED超過在主控台設定的每秒、每日限制。會附上內文 retryAfterSeconds 與 Retry-After 標頭無
500(無)伺服器錯誤。此請求中已扣除的金額會在回應後退還退款
503SERVICE_DEGRADED暫時性的資料庫連線問題。Retry-After: 30 — 30 秒後再試退款

錯誤回應內文格式:{"success": false, "statusCode": 400, "code": "INVALID_LOCATION", "message": "...", "timestamp": "..."} — code 只在有值時附上。請以 statusCode 與 code 分支,不要依賴 message 的文字。

// 401 — key missing or invalid
{ "success": false, "statusCode": 401, "message": "Invalid or missing API key", "error": "Unauthorized", "timestamp": "2026-10-12T03:00:00.000Z" }

// 400 — body validation failed (message is an array)
{ "success": false, "statusCode": 400, "message": ["property foo should not exist", "month must not be greater than 12"], "error": "Bad Request", "timestamp": "2026-10-12T03:00:00.000Z" }

// 404 — feature not enabled for the account (message: "This feature is not available yet")
{ "success": false, "statusCode": 404, "code": "ziwei_not_enabled", "message": "아직 열리지 않은 기능입니다", "timestamp": "2026-10-12T03:00:00.000Z" }

// 429 — request limit set in the console (message: "Per-second request limit exceeded. You can adjust it in console > API keys > Request limits.")
{ "success": false, "statusCode": 429, "code": "RATE_LIMIT_EXCEEDED", "message": "초당 요청 제한을 초과했어요. 콘솔 > API 키 > 요청 제한에서 조정할 수 있어요.", "retryAfterSeconds": 1, "timestamp": "2026-10-12T03:00:00.000Z" }

各 API 代碼中常見的有:422 無法處理的輸入(PROMPT_TOO_LONG、EXTRACTION_FAILED)、503 暫時無法使用(例:無法載入解讀段落,不計費)、504 外部模型逾時。訪客體驗上限為 429 GUEST_QUOTA_EXCEEDED。

回應警告(warnings)

請求成功,但因無法辨識部分輸入而以預設值計算時,成功回應的 data 最上層最後會附上 warnings 陣列。狀態碼仍為 200,費用也相同。沒有警告時就不會有 warnings 鍵 — 回應與以往完全相同。每個項目只有 {"code", "field"},不會回傳您傳送的值(出生資訊)。同一問題出現在多個欄位時,每個欄位各回傳一筆。

代碼含義出現的欄位
UNKNOWN_TIMEZONE無法辨識時區名稱,因此以預設時區計算。請確認是否有錯字(例:Asia/Seol)。省略或為空值時不會警告萬年曆、八字特質、八字↔MBTI 比較、今日運勢、終身八字、訪客萬年曆 的 timezone、KB 解讀 的 birth.timezone、合盤 的 personABirthTimezone · personBBirthTimezone
// 200 — calculated with the default time zone, only a warning is added
{ "success": true, "data": { "wonkuk": { ... }, ..., "warnings": [ { "code": "UNKNOWN_TIMEZONE", "field": "timezone" } ] } }

速率限制

服務保護上限一律生效:每個 API 金鑰每分鐘 300 次(來自同一 IP 的金鑰請求合計每分鐘 3,000 次)。超過時回傳 429,此時回應中沒有 code 與 Retry-After — 請稍後(最多 1 分鐘)再試。比這更低的限制由合作夥伴自行設定 — 在主控台 API 金鑰 > 請求限制 中設定每秒請求與每日請求(以 KST 為準),即可防止金鑰外洩或無限迴圈耗盡餘額。留空時只套用上述服務保護上限。

計費

所有 API 呼叫都從點數中扣除。新註冊時提供免費 ₩1,000 點數(若觸發防止不當註冊的條件,可能暫緩發放)。訪客每月最多可免費測試 5 次。

API 價格
manseryeok(萬年曆) ₩50/次
compat(合盤) ₩20/次
lifetime(終身八字) 全部 ₩100/次 · 單一主題 ₩20/次 · 星座、紫微斗數層 +₩20/層
ziwei-chart(紫微斗數命盤) ₩50/次 · readings: true +₩20(合計 ₩70)
identity(八字特質,舊端點) ₩10/次 — 新串接請使用萬年曆的 identity 欄位(不另收費)
saju-mbti(八字↔MBTI 比較) ₩10/次(與八字特質相同價格)
today(今日運勢) ₩10/次
dream(解夢) ₩30/次(無結果時 ₩0)
natal-chart(本命盤) ₩20/次 · readings: true ₩40/次
personality-type(性格類型)- 免費 ₩0(免費)
personality-type(性格類型)- 進階版 ₩10/次
reading(AI 八字解讀) 以 token 計價(依使用的 token 數而異)
image(八字圖片) ₩200/張
image_generation(圖片生成 · 模型轉售) 依模型、解析度、品質每張固定價格 — 價目表

訪客測試

冪等性

每個成功的請求都會個別計費。再次傳送相同請求會重新計算、生成並再次計費,因此重試造成的重複或相同輸入的重複使用,請由用戶端儲存回應來處理(例:以請求雜湊為鍵的快取)。

X-Idempotency-Key 標頭(最多 128 字 — 更長時只記錄前 128 字)仍可傳送,但不會防止計費。傳送的鍵會原樣記錄在用量紀錄的 idempotencyKey 中,可用來將哪個請求以哪次呼叫處理,與合作夥伴端的訂單、工作 ID 對照。

例外:面相、手相解讀在 24 小時內以相同的鍵、相同的內文再次傳送時,會回傳第一次的結果,不會重新計費(重試與重新傳送)。

例外:姓名學在 24 小時內以相同的鍵、相同的內文再次傳送時,會回傳第一次的結果,不會重新計費(重試與重新傳送)。

支援

串接過程中遇到困難,或回應與文件不符時,請告訴我們。

洽詢聯絡方式
技術支援 · 故障回報 · 合作 contact@float.do

洽詢時一併提供下列資訊,可加快確認速度。

關於條款與個人資料處理事項,請參考使用條款(韓文)與隱私權政策(韓文)。