API 指南
想知道這套 API 在實際服務中如何運作嗎? 您可以在以同一套引擎運作的 AI 八字應用程式 INTA – Life is Timing 中,親自體驗八字分析與 AI 對話。 INTA 就是這套 API 的實際運作範例。 INTA 的 AI 語音回應(TTS)也由同一套技術堆疊驅動 — 語音 API 將於日後公開。
交給 AI 打造應用程式 — 免費電子書(韓文)
挑選書籍(韓文)綜合運勢應用程式(韓文)角色聊天應用程式(韓文)會員制網頁應用程式(韓文)Apps in Toss 迷你應用程式(韓文)
快速入門
HRUM 提供會記憶的 AI、八字分析與 LLM 轉售。請依照以下 3 個步驟開始:
基本網址為 https://api.hrum.ai(API)與 https://console.hrum.ai(主控台)。舊網址 api.float.do、console.float.do、api.inta.do 仍可正常使用,若已完成串接則無須更改。
- 取得 API 金鑰 - 在主控台註冊後,於 API 金鑰畫面中建立金鑰(金鑰僅在建立後顯示一次)。從註冊到錯誤處理的完整流程,請參閱開發者入門指南。
- 發送請求 - 依照下方範例發送 POST 請求。
- 處理回應 - 從 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 轉售。
- 變更(2026-10-14): 韓文回應的語氣統一為一致的敬語體(內容與欄位皆無變更)
- 新增(2026-10-14): 無法辨識時區名稱時,成功回應會附上
warnings(UNKNOWN_TIMEZONE)。計算仍和以往一樣使用預設時區,沒有警告時回應與以往相同 — 回應警告 - 新增(2026-10-17): AI 八字解讀、解讀記憶、報告的
birth現在可接受與萬年曆 API 相同的出生地、時區、閏月欄位(isLeapMonth、timezone、座標、country、zaSiRule、birthTimePrecision)。未傳送時計算與以往相同 — AI 八字解讀 API
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_FLAGGED | 400 | 遭內容審核封鎖(ridm:system+user,轉售:user 訊息) |
INSUFFICIENT_BALANCE | 402 | 餘額不足(會先預留所要求的完整輸出再檢查) |
MODEL_NOT_FOUND | 400 | 未設定的模型 |
INVALID_TOOLS / TOOLS_UNSUPPORTED_FOR_MODEL | 400 | tools 相關欄位不一致 / 對 Claude 模型要求工具呼叫 |
FILE_NOT_FOUND | 400 | fileIds 中含有不存在的檔案(或其他合作夥伴的檔案) |
FEATURE_DISABLED | 403 | 在已關閉 youtube、files、emotion 功能的帳號中使用該選項 |
RATE_LIMITED | HTTP 400,本文 status 429 | 上游速率限制,或超過轉售每日支出上限(每個合作夥伴預設 ₩100,000/日) |
UPSTREAM_TIMEOUT | HTTP 400,本文 status 504 | 上游回應逾時(60 秒) |
UPSTREAM_INVALID_REQUEST | 400 | 上游模型拒絕請求(上游 400、422) |
INVALID_RESPONSE_FORMAT | 400 | 使用 response_format: json_object,但訊息中沒有「json」一詞(OpenAI 系列) |
REPORT_ONLY_MODEL | 400 | 指定了 ridm/saju-report — 僅限八字報告 API使用 |
| (無) | 400 | ridm/* 模型缺少 user、systemPrompt 超過 8,000 字、不支援的模型前綴 |
provider_not_configured | 503 | 目前未連接 Claude 模型 |
注意事項
- 插入 YouTube 字幕: youtube:true 時,會從最後一則訊息的 YouTube 連結擷取字幕並計入輸入 token。若無法取得字幕,對話會在不插入的情況下照常進行,回應的
youtubeUsed會是空陣列(只有獨立的 YouTube 摘要 API 會回傳 400 且不計費)。 - 相容原始模型: model 值指定為 openai/*、google/*、anthropic/* 時,會以不含記憶功能的方式直接呼叫原始模型(成本 × 匯率 × 1.10)。
- 提示快取折扣: OpenAI 系列模型(openai/*、ridm/gpt-*)重複傳送相同的前段內容(1,024 token 以上)時,命中上游快取的輸入 token 會以輸入單價的 30% 計費。可透過回應的
usage.prompt_tokens_details.cached_tokens與GET /usage/logs的cachedTokens確認,是否命中快取可能依上游政策而每次呼叫不同。Google 模型沒有快取,因此適用全額輸入單價。 Claude 模型也不會要求快取,因此適用全額輸入單價。 - 不適用 REPORT_ONLY_MODEL: ridm/saju-report 是無記憶的單次專用模型,無法在此端點使用(400)。
自訂個人資料(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 沒有專屬的錯誤代碼,只會回傳共通錯誤。
上限與限制
- 欄位上限: 每位終端使用者最多 100 個欄位。超過時會從最舊的欄位開始刪除。
- 值的長度: 每個欄位預設 150 字,最多 500 字。可透過 profileValueMaxChars 調整。
- 累積儲存: 以 extractProfileFields 擷取的值會累積保存,空值或 null 會略過並保留既有的值。只有透過上方的 DELETE API(或超過 100 個時依舊到新順序自動刪除)才會刪除欄位。以 endUserProfile 指定的值會覆寫擷取值。
- 值長度以請求為單位: profileValueMaxChars 不會被保存,只套用於該次請求中儲存的值。
- Soft Update: 即使結構描述(欄位名稱)變更,既有的值也會保留,並在每次呼叫時與新值合併。
- 僅限 ridm/*: 轉售模型(openai/*、google/*)會忽略個人資料。
LLM API(轉售)
轉售 openai/*、google/* 等原始 LLM 模型(無記憶,原始回應原樣傳回)。轉售模型的請求中,user、systemPrompt、recallCount、memoryCap、summaryEvery、emotion、candor 會被忽略(系統指示請以 {"role":"system"} 放進 messages),回應中也不會有記憶欄位(recalledMemories 等)。價格=成本 × 匯率 × 1.10。
提供的模型(與 GET /api/v1/partners/v1/models 相同的清單)
- OpenAI(23 款):
openai/gpt-6-astra·openai/gpt-6-sol·openai/gpt-6-luna·openai/gpt-5.6-sol·openai/gpt-5.6-terra·openai/gpt-5.6-luna·openai/gpt-5.5·openai/gpt-5.4·openai/gpt-5.4-mini·openai/gpt-5.4-nano·openai/gpt-5.2·openai/gpt-5.1·openai/gpt-5·openai/gpt-5-mini·openai/gpt-5-nano·openai/gpt-4.1·openai/gpt-4.1-mini·openai/gpt-4.1-nano·openai/gpt-4o·openai/gpt-4o-mini·openai/o3·openai/o3-mini·openai/o4-mini - Google(3 款):
google/gemini-3.5-flash·google/gemini-3.5-flash-lite·google/gemini-3.1-pro - Anthropic(13 款): 請參閱下方的 Claude 模型說明
- RIDM: 上述每個模型都有在相同名稱前加上
ridm/前綴的記憶型模型(轉售價 × 1.3),另有八字報告專用的ridm/saju-report(只能透過/reading/report呼叫)。
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),會回傳 400TOOLS_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 | 解讀文字 |
sajuSource | computed(以 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 | 代碼 |
|---|---|
| 400 | MISSING_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) |
| 402 | INSUFFICIENT_BALANCE — 呼叫前會先預留 maxLength × 2 token(value 等級或非韓文的問題另加 4,000)的輸出費用,因此即使最終金額較小,也可能遭到拒絕 |
| 403 | FEATURE_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 |
- 計費: 在既有的 token 價格(問題+persona+納入項目依據區塊的字數 × 0.25 作為輸入 token,再加上輸出 token)之上,每個納入的項目再加上該項目單獨端點 1 次的價格。依據區塊是每個項目 1,500 字以內的摘要。帳號中已關閉該功能或沒有價格的項目不會納入。各項目費用與單次預估範圍請見價格頁面。
- 只傳送四柱(
saju)的請求沒有出生年月日,因此不會納入紫微斗數、占星(解夢、塔羅仍會納入)。 - 與
tools.astrology的關係: 納入占星項目時,為避免重複放入同一張本命盤,會略過tools.astrology的星盤插入。若排除占星項目(exclude或功能關閉),tools.astrology會照現在的方式運作。 - 解夢安全機制: 若
dream內容為危機表述,不會呼叫 AI,而是以costPoints: 0回傳求助資訊(support)。 - 功能開關: 目前為開啟狀態。若伺服器設定關閉,即使傳送
exclude、dream、tarot也會被忽略,解讀、價格、回應都會與沒有納入項目時相同(沒有modulesUsed、moduleFees、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 | 紫微斗數 AI | birth+出生時刻(hour) | token 價格+/ziwei-chart 1 次的價格 |
astro | 占星 AI | birth(沒有時刻也可以) | token 價格+₩20(占星項目的固定費用) |
tarot | 塔羅 AI | tarot 選項 — 不需要 birth | token 價格+/tarot 1 次的價格 |
dream | 解夢 AI | dream 夢境內容 — 不需要 birth | token 價格+/dream 1 次的價格 |
- 計費: token 價格(問題+persona+僅該 AI 的一個依據區塊,字數 × 0.25 作為輸入 token,再加上輸出 token)+該項目的 1 筆固定費用。各領域的單次預估價格請見價格頁面。
- 不可與
exclude同時使用: 兩者都傳送時回傳 400ONLY_WITH_EXCLUDE。缺少該 AI 所需的輸入時回傳 400ONLY_REQUIRES_INPUT,帳號中已關閉該功能時回傳 400ONLY_DOMAIN_UNAVAILABLE— 不會改以八字解讀代替回答。若為無法計算命盤、星盤的日期,則回傳 400ONLY_INPUT_INVALID。 tarot、dream不需要出生年月日。 不必傳送birth、saju,只要傳送問題與牌(或夢境內容)即可。only不是saju時不會使用八字,因此回應中沒有sajuSource。- 功能開關: 與納入項目適用相同的伺服器設定,目前為開啟狀態。設定關閉時,
only會被忽略,運作方式與既有的八字解讀相同。
請求範例 — 僅塔羅 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
}
}
注意事項
- 只回傳解讀結果: 回應中只包含產生的運勢解讀文字,不會公開內部提示或八字理論。
candorApplied: 只有在以t傳送candor時,回應才會附上實際套用的直言度(t|f)。/reading/memory也相同(直言度(暫定名稱))。- 計費依據: 輸入=(question+persona 的字數)× 0.25 token(+在
/reading中插入的 YouTube 字幕字數 × 0.25),輸出=實際的 completion token。八字插入與系統提示不計費,usage.inputTokens僅供參考。開啟納入項目(今日運勢 · 紫微斗數 · 占星 · 解夢 · 塔羅)時,會加上其依據區塊與各項目的固定費用。costPoints 為實際扣款金額。 - 回應語言: 非韓文的問題會以與問題相同的語言回答。
- 出生時間不詳: 省略 hour 時,會排除時柱,以年、月、日三柱為準進行解讀。
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 | 代碼 | 發生時機 |
|---|---|---|
| 400 | MISSING_ENDUSER_ID | endUserId 為空或只有空白 |
| 400 | MISSING_SUBJECT_INPUT · INVALID_SAJU_PILLAR · INVALID_LUNAR_DATE | 出生資料、八字輸入錯誤(與解讀 API 相同) |
| 400 | UNKNOWN_TOOL · INVALID_TOOL_MODE · INVALID_FILE_IDS · FILE_IDS_TOO_MANY · INVALID_FILE_ID_TYPE · FILE_NOT_FOUND | tools、fileIds 錯誤。此路徑也接受 tools.emotion、tools.summaryEvery |
| 400 | ONLY_WITH_EXCLUDE · ONLY_REQUIRES_INPUT · ONLY_DOMAIN_UNAVAILABLE · ONLY_INPUT_INVALID | 與單獨呼叫一個 AI 相關的錯誤 |
| 402 | INSUFFICIENT_BALANCE | 無法預先預留輸出費用(方式與解讀 API 相同) |
| 403 | FEATURE_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 | 代碼 | 發生時機 |
|---|---|---|
| 404 | END_USER_NOT_FOUND | 第一次出現的 endUserId(除了儲存對話以外的四個路徑共通) |
| 400 | MISSING_PARAM | 搜尋 — 缺少 endUserId |
| 400 | MISSING_TAGS | 搜尋 — tags 為空 |
| 400 | ENDUSER_ID_TOO_LONG | 儲存對話 — endUserId 超過 255 字 |
注意事項
- 1.3 倍單價: 由於託管記憶,輸入/輸出 token 單價為 AI 八字解讀的 1.3 倍(每 1M token:輸入 3,754 韓元、輸出 30,030 韓元,VAT 另計)。
- endUserId 必填: 每位終端使用者都必須有唯一的 ID,以相同 ID 呼叫時會保留過去的上下文。
- 記憶保存: 已儲存的記憶會保存到明確刪除為止。
八字報告 API
不需要提問,按一下按鈕就能一次取得所有八字解讀,從總評、財運、感情到大運。這是與對話型(reading)分開、單次付款的商品。預設使用專用模型 ridm/saju-report(RIDM 自家的報告特化模型 — 由於是單次商品,不搭載記憶)。解讀 API 的回應上限為 2,000 字 — 若需要更長的詳細解說(最多 12 節,約 6,000 字),請使用此報告 API。
POST /api/v1/partners/v1/reading/report
輸入出生年月日(或八字),即可取得依章節分段的 Markdown 八字報告。
請求參數
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| birth | object | birth 或 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") |
| saju | object | birth 或 saju 擇一 | 直接輸入四柱 {"year":{"stem":"경","branch":"오"},"month":{…},"day":{…},"hour"?:{…}} |
| year / month / day / gender | number / string | 選填 | 平面欄位(舊版,國曆)。只有四個值全部齊備時才視為 birth。birth、saju 皆未提供時回傳 400 MISSING_SUBJECT_INPUT |
| hour / minute | number | 選填 | 省略 hour 時,會排除時柱,以年、月、日三柱為準進行解讀。未提供 hour 而只傳送 minute 時會被忽略 |
| tone | string | 選填 | warm(預設) | casual | formal |
| candor | string | 選填 | 直言度 — t | f(預設)。只會改變優點與困難點的安排與強度,章節結構以及不對醫療、法律、投資做出確切答覆的限制維持不變。不計費。請參閱直言度(暫定名稱) |
| persona | string | 選填 | 語氣、角色指示(最多 2,000 字 — 只有這部分的長度以輸入計費) |
| sections | string[] | 選填 | 章節標題清單(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)
}
}
- 八字插入免費: 萬年曆計算、插入與系統提示不計費。輸入只依 persona 長度計費,輸出則依實際使用的 token 計費。
- 實測費用: 預設 8 個章節(約 3,000 字)的報告 1 次約 85P(以輸出 ₩38,077/1M 為準)。
- 重試會再次計費。 收到回應後若想以相同輸入重複使用,請在用戶端儲存(冪等性)。
錯誤代碼
除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳以下代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 400 | MISSING_SUBJECT_INPUT | birth、saju 皆未提供 |
| 400 | INVALID_SAJU_PILLAR | saju 的柱不屬於六十甲子 |
| 400 | INVALID_LUNAR_DATE | 不存在的農曆日期 |
| 402 | INSUFFICIENT_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"
}
}
注意事項
- 必須有字幕: 沒有字幕時回傳 TRANSCRIPT_UNAVAILABLE 400(不計費)。
- 錯誤: 錯誤的 URL、ID 回傳 400
INVALID_YOUTUBE_URL/ 摘要產生失敗回傳 400LLM_GENERATION_FAILED/ 餘額不足回傳 402INSUFFICIENT_BALANCE。 - 計費: 以 token 計費。依使用模型(預設
ridm/gpt-5.6-terra)的轉售價原價(成本 × 1.1)計算 — 由於沒有記憶層,不會套用 RIDM Memory 單價(× 1.3)。costPoints=無條件進位(輸入 token × 輸入單價+輸出 token × 輸出單價),單價以 1M token 為準(VAT 另計)。 - 實測費用: 20–30 分鐘的影片 1 次約 60P(含 token)。
- 與解讀串接: 在 AI 八字解讀 API(
/reading)中,可用tools: { "youtube": true }插入問題中連結的字幕(最上層的youtube欄位會被忽略)。YouTube 插入僅支援 /reading(/reading/memory 尚未支援)。傳送到 /reading/memory 時不會取得字幕,而是在toolsSkipped中以{"tool": "youtube", "reason": "unavailable"}告知。
錯誤代碼
除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳以下代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 400 | INVALID_YOUTUBE_URL | 無法從 URL 找到影片 ID |
| 400 | TRANSCRIPT_UNAVAILABLE | 沒有字幕的影片(不計費) |
| 400 | LLM_GENERATION_FAILED | 摘要產生失敗或結果為空 |
| 402 | INSUFFICIENT_BALANCE | 無法預先預留摘要費用 |
| 403 | FEATURE_DISABLED | 帳號中已關閉 YouTube 功能 |
開啟與關閉功能
YouTube 摘要 API 可依合作夥伴帳號及請求單位選擇啟用。在主控台的「功能設定」中管理全域啟用狀態;chat 需明確指定最上層的 youtube:true,reading 則需明確指定 tools: { "youtube": true },以按請求啟用。
- 全域停用: 回應 403 { code: 'FEATURE_DISABLED', feature: 'youtube' }
- 請求單位: 未指定
youtube:true或為 false=不插入 YouTube 內容
文件處理 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 只有在有自動回想的檔案時才會附上(為空時省略)。
價格與計費
- 上傳與擷取: 免費(文字擷取的 token 不計費)
- AI 分析(analyze=true): 依邊界偵測+各區段摘要+整體摘要實際使用的 token 量,以分析模型單價計費。同步 ≤30,000 字,非同步 >30,000 字(status:
analyzing) - Chat 插入: 文件文字會計為輸入 token,計費方式與一般 chat 請求相同
- 紀錄: 可在主控台的使用紀錄中,以
file_upload(免費)、file_analyze(付費,依實際使用 token)分類確認
開啟與關閉功能
文件處理功能可在合作夥伴帳號層級啟用或停用。在主控台的「功能設定」中管理,停用時所有檔案請求都會回傳 403。
- 全域停用: 回應 403 { code: 'FEATURE_DISABLED', feature: 'files' }
- 請求單位: 未指定
fileIds=不插入文件(正常處理)
分析狀態與區塊
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 |
分析失敗(回應中不包含失敗原因 — 請重新上傳) |
注意事項
- 格式驗證: 不支援的格式會回傳 400 { code: 'INVALID_FILE_TYPE' }
- 其他錯誤: 缺少檔案回傳 400
FILE_NOT_PROVIDED/ 超過 10MB 回傳 400FILE_TOO_LARGE/ 不存在的檔案回傳 404FILE_NOT_FOUND/:id不是 UUID 時回傳 400 - 分析必填項目: analyze=true 時若沒有 endUserId,會回傳 400 { code: 'END_USER_REQUIRED' }
- 擷取失敗: 擷取文件時發生錯誤會回傳 422 { code: 'EXTRACTION_FAILED' }
- 餘額確認: 分析請求前會檢查合作夥伴的點數是否足夠。不足時回傳 402
- 自動存入知識庫: analyze=true 時,各區段的摘要與標籤會自動儲存到知識庫,之後成為 auto-recall 的對象。指定 endUserId 時,也會加入該使用者的記憶層。
- 重新上傳=新檔案: 每次上傳都會建立新檔案(新 id),analyze=true 時會再次分析並計費。相同的文件請只上傳一次,並以
fileIds重複使用取得的 id。
錯誤代碼
除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳以下代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 400 | FILE_NOT_PROVIDED | 上傳 — 沒有 file 部分 |
| 400 | INVALID_FILE_TYPE | 上傳 — 不支援的格式 |
| 400 | FILE_TOO_LARGE | 上傳 — 超過 10MB(視情況可能回傳不含代碼的 413) |
| 400 | END_USER_REQUIRED | 上傳 — analyze=true 但沒有 endUserId |
| 400 | (無) | 詳細資料、刪除 — :id 不是 UUID |
| 402 | INSUFFICIENT_BALANCE | 上傳 — 無法預先預留分析費用 |
| 403 | FEATURE_DISABLED | 帳號中已關閉文件處理功能(四個路徑共通) |
| 404 | FILE_NOT_FOUND | 詳細資料、刪除 — 不存在的檔案或其他帳號的檔案 |
| 422 | EXTRACTION_FAILED | 上傳 — 無法從文件中擷取文字 |
情緒狀態分析(Emotion)
搭配 Chat API 的摘要週期,分析使用者與 AI 的情緒狀態。不會另外呼叫 LLM,只是在摘要提示詞中加入情緒分析區塊,因此不會額外計費。僅支援 ridm/* 模型。
總覽
啟用條件:
- 全域:
partner_emotion_enabled✓ - 合作夥伴:在主控台的功能設定中啟用「情緒狀態分析」
- 請求:明確指定
emotion: true - 模型:僅支援
ridm/*系列
摘要週期(summaryEvery)
情緒分析會在每個摘要週期自動執行。可用 summaryEvery 參數調整週期(預設值:5,範圍:1–20)。
- summaryEvery=1:幾乎每一輪都更新情緒(摘要在回應之後以非同步方式執行)
- summaryEvery=5:每 5 輪(建議)
- summaryEvery=20:每 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)
- improving:非正向情緒(sadness+anger+fear+disgust)減少 50 以上
- stable:變化未滿 50
- declining:非正向情緒增加 50 以上
- null:沒有前一個週期的資料
串流回應範例(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]
費用說明
- 不另外計費:情緒分析包含在摘要週期的提示詞中進行,摘要與情緒週期的 token 不會向合作夥伴計費。計費的只有聊天輪次本身的輸入與輸出 token。
注意事項
- 第一個週期之前:在第一個摘要週期執行之前不會有 emotion 欄位(屬正常行為)。
- 功能關閉時:請求為
emotion: true,但全域或合作夥伴的功能設定未啟用時,回傳 403 { code: 'FEATURE_DISABLED', feature: 'emotion' }(與 YouTube、文件處理相同)。未傳送emotion或為 false 時,只會省略該欄位。 - 僅支援 ridm/* 模型。已開啟情緒功能的帳號,轉售(openai/*、google/*)請求中的 emotion 欄位會被忽略;已關閉的帳號則不論模型為何,
emotion:true都會回傳 403FEATURE_DISABLED。 - 串流:在串流回應中,emotion 會包含在 message_done SSE 事件裡。
八字圖片 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
}
}
注意事項
- 固定價格:每次產生圖片計費 ₩200。
- 產生時間:產生圖片約需 20~30 秒,請將逾時時間設定得充裕一些。
- Base64 編碼:回傳的 imageDataUri 是以 base64 編碼的 PNG 圖片,可直接用於 HTML
<img src="{imageDataUri}">標籤。 - 風格:background(背景藝術)、icon(極簡圖示)、portrait(肖像插畫)只改變氛圍。所有風格的尺寸都相同(預設 1024×1024 正方形)。
- 逾時:若上游未在 80 秒內回傳圖片,會回傳 504
IMAGE_UPSTREAM_TIMEOUT且不計費。請重新嘗試。 - 出生時間不明:省略 hour 時,會去掉時柱,以年、月、日三柱為基準解讀。
錯誤代碼
除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 402 | INSUFFICIENT_BALANCE | 餘額少於 1 張圖片的價格 |
| 504 | IMAGE_UPSTREAM_TIMEOUT | 80 秒內未收到圖片(不計費) |
圖片生成 API(模型轉售)
POST /api/v1/partners/v1/images/generations
以與 OpenAI Images API 相同的格式,用一把金鑰呼叫 GPT-Image 與 Nano Banana 模型。每個模型、解析度、品質都有固定的每張價格,表中金額會直接扣除(產生張數 × 每張價格)。提示詞的輸入 token 費用已包含在每張價格中,不會另外加收。
請求參數
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
model | string | O | openai/gpt-image-2, openai/gpt-image-1-mini, google/nano-banana-pro, google/nano-banana, fal/nano-banana-pro, fal/nano-banana |
prompt | string | O | 要產生的圖片描述(最多 1,000 字)。超過時回傳 422 PROMPT_TOO_LONG(因為在預留餘額之後才檢查,餘額不足時會先回傳 402),空字串回傳 400 EMPTY_PROMPT |
size | string | GPT-Image:1024x1024(預設)、1024x1536(直式)、1536x1024(橫式)、auto(由模型選擇,以該品質中最貴尺寸的價格計費)。舊值 256x256、512x512 會以 1024x1024,1792x1024 以 1536x1024,1024x1792 以 1024x1536 產生並計費。在 Nano Banana 中只當作比例使用,建議改用 aspect_ratio。 | |
quality | string | 僅限 GPT-Image:low、medium(預設)、high。舊值 standard=medium、hd=high 仍可照常使用。對 Nano Banana 傳送 low/medium/high 會回傳 400。 | |
aspect_ratio | string | 僅限 Nano Banana:21:9、16:9、3:2、4:3、5:4、1:1(預設)、4:5、3:4、2:3、9:16。比例不影響價格。優先於 size。 | |
resolution | string | 僅限 Nano Banana:Nano Banana 只支援 1K,Nano Banana Pro 支援 1K(預設)、2K、4K。K 只接受大寫。 | |
n | number | 產生張數 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": "..."
}
- GPT-Image 與 Google 直接模型以
b64_json回傳圖片,FAL 模型以url回傳。 costWon= 每張價格 × 實際產生的張數。若上游一張圖片都沒有回傳,則不計費。- GPT-Image 回應中的
usage(token 數)僅供參考,不用於計價。
錯誤代碼
除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 400 | MODEL_NOT_FOUND | 價目表中沒有的模型 |
| 400 | INVALID_MODEL | openai/、google/、fal/ 以外的前綴 |
| 400 | INVALID_PARAMETER | 模型不接受的選項(對 GPT-Image 傳 aspect_ratio、resolution,對 Nano Banana 傳 quality,不支援的解析度) |
| 400 | EMPTY_PROMPT | 提示詞只有空白 |
| 400 | INVALID_PROMPT | 上游模型拒絕提示詞 |
| 400 | UPSTREAM_ERROR | 上游錯誤或圖片 0 張(不計費) |
HTTP 400,本文 status 429 | RATE_LIMITED | 上游速率限制,請稍後再試 |
| 402 | INSUFFICIENT_BALANCE | 每張價格 × n 大於餘額 |
| 422 | PROMPT_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 之後再查詢 |
succeeded | result = 同步呼叫原本會回傳的 200 回應(data、costWon、requestId) |
failed | error = 同步呼叫原本會回傳的錯誤本文(statusCode、code、message),不計費 |
- 計費:只在結果就緒的那一刻扣除一次。等待期間會先從餘額預留預估金額,若失敗或逾時,預留會解除且不計費。查詢多次也不會重複計費。
- 保存期限:結果與錯誤可在建立工作後 24 小時內查詢,之後即刪除(之後回傳 404)。若圖片為
b64_json,查詢回應也會同樣龐大(每張數 MB),收到後請立即儲存。若整體結果超過 16MB,將不會保存,並以IMAGE_JOB_RESULT_TOO_LARGE判定失敗(不計費),請減少張數(n)或解析度。 - 其他合作夥伴的工作 ID、不存在的 ID、超過保存期限的 ID,一律回傳相同的 404
IMAGE_JOB_NOT_FOUND。
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 202 | — | Prefer: respond-async 請求未在 60 秒內完成,請以上述工作 ID 查詢 |
| 404 | IMAGE_JOB_NOT_FOUND | 不存在、已過期或屬於其他合作夥伴的工作 ID |
| 429 | IMAGE_JOB_POLL_RATE_LIMITED | 同一把 API 金鑰在 2 秒內再次查詢,請於 Retry-After 秒後再試 |
error.statusCode 504 | IMAGE_UPSTREAM_TIMEOUT | 240 秒內未收到圖片(不計費) |
error.statusCode 413 | IMAGE_JOB_RESULT_TOO_LARGE | 結果超過 16MB(不計費) |
error.statusCode 503 | IMAGE_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"。校正結果的格式請參閱下方注意事項中的農曆輸入範例。
注意事項
- 回應內容複雜:萬年曆回應不只包含命盤,還有大運、流年、格局、神煞等詳細資訊。請只選用需要的欄位。
- 選用欄位:出生時間不明的約定:
hour、minute可以省略。省略hour時,不會假設為正午,而是去掉時柱。回應會有以下差異。wonkuk.hour=null、trueSolarTime=nullohaengBalance= 以年、月、日三柱(天干+地支 6 字)為基準重新計算branchRelations、cheonEulGwiIn= 只保留僅憑三柱地支即可成立的項目- 頂層新增
birthHour:{ known: false, hourPillar: null, basis: "three_pillars", excludedFields: [], note }。分析欄位(yongshin、strength、gyeokguk、hapChungReport、ilganSummary、seun等)不會被移除,而是以年、月、日三柱(6 字)為基準計算後回傳(依字數而定的門檻值也換算為 6 字基準)。這不是假設正午的參考值,而是只用三柱算出的值 - 判斷是否不明請使用
birthHour.known,不要用excludedFields.length判斷。此陣列現在一律為空,只為了相容舊版用戶端而保留 - 未帶
hour而送出的minute會被忽略(只有在有hour時才是minute ?? 0) - 有傳送
hour的請求沒有birthHour欄位,計算結果也與以往相同(2026-10-10 起附加的identity、ohaengDeficient除外)。一向都傳送hour的既有用戶端不受影響。若用戶端是依照短暫存在過的「省略時以正午計算」行為所製作,請確認birthHour.known === false,並將時柱欄位顯示為「不明」。strength、gyeokguk等一律以三柱基準值回傳(2026-09-16 以前會被移除)。諮詢類 API(/reading、/reading/memory、/reading/report)也依相同規則,將三柱基準值傳給模型
- 韓文欄位名稱:所有欄位名稱(天干、地支、五行等)皆以韓文標示。即使傳送
lang,欄位名稱也不會改變,只會翻譯值(用神、日干說明、大運方向、神煞名稱等)。天干、地支、五行代碼(stem、branch、ohaeng)與ohaengBalance的鍵在所有語言中都維持韓文。完整清單請參閱有效值 > 與語言無關的代碼值。 - 新增選項全部為選填(2026-10-08):若完全不傳送
lang、calendar、isLeapMonth、birthLatitude、birthLongitude、country、zaSiRule、birthTimePrecision,計算結果與以往相同。但自 2026-10-10 起,回應末尾一律會加上identity、ohaengDeficient(既有鍵的值與順序不變)。價格也維持 ₩50/次。 - 變更(2026-10-12):農曆轉換基準改為韓國天文研究院(KASI)資料,部分日期的結果有所變動。不存在的閏月不會轉成平月,而是回傳 400
INVALID_LUNAR_DATE。 - 農曆輸入:以
calendar: "lunar"傳送時,回應頂層會附上轉換明細lunarInput。真太陽時校正結果會放在trueSolarTime。引擎實際輸出範例(農曆 1990-07-15 14:30,釜山座標,lang: "en"):{ "year": 1990, "month": 7, "day": 15, "hour": 14, "minute": 30, "timezone": "Asia/Seoul", "gender": "male", "calendar": "lunar", "birthLatitude": 35.1796, "birthLongitude": 129.0756, "lang": "en" } → "lunarInput": { "calendar": "lunar", "lunarDate": "1990-07-15", "isLeapMonth": false, "leapMonthApplied": false, "solarDate": "1990-09-03" }, "trueSolarTime": { "originalLocal": "14:30", "correctedLocal": "14:07", "longitudeCorrection": -23.6976, "equationOfTime": 0.3241, "totalCorrectionMinutes": -23.4, "dayShift": 0, "dstApplied": false, "basis": "coords", ... }, "ilganSummary": "辛 Metal — Jewel energy. Sharp intellect and refined aesthetic sense.", "daeunDirection": "Forward" - 輸入錯誤:不存在的農曆日期(例:只到 29 日的月份的 30 日)回傳 400
INVALID_LUNAR_DATE,只傳送緯度/經度其中之一的請求回傳 400INVALID_LOCATION,都不計費。缺少timezone等格式錯誤也回傳 400(不計費)。
錯誤代碼
除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 400 | INVALID_LUNAR_DATE · INVALID_LOCATION | 不存在的農曆日期/只傳送緯度、經度其中之一(不計費) |
| 402 | (無) | 餘額少於呼叫價格:此 API 呼叫前不檢查餘額,因此會收到沒有代碼的 402 |
終身八字 API
POST /api/v1/partners/v1/lifetime
依出生年月日時計算命盤,並把對應此命盤的組件(日柱、日干×月支、日干×身強弱、日干×用神、五行過多/不足最多 3 個、最強的十神群組)的解讀段落,整理成性格、財運、事業、感情、健康、人際關係、建議 7 個主題回傳。段落依 HRUM 八字理論撰寫,相同輸入一律得到相同結果。命盤判定與萬年曆 API 相同。
請求參數
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
year · month · day | number | O | 出生年(1900-2100)、月、日(預設國曆,calendar: "lunar" 時為農曆) |
hour · minute | number | 出生時刻。省略 hour 時,以與萬年曆 API 相同的出生時間不明規則(年、月、日三柱基準)計算 | |
timezone | string | O | 時區(例:Asia/Seoul)。無法辨識的名稱會以預設時區計算,並在回應中附上警告(UNKNOWN_TIMEZONE) |
gender | string | O | "male" 或 "female" |
topic | string | 只取得一個主題時:personality、wealth、career、love、health、relationships、advice。省略時為全部 7 個主題 | |
lang | string | ko(預設)、en、ja、th | |
layers | string[] | 附加解讀層:"astro"(星座:太陽、月亮、上升星座)、"ziwei"(紫微斗數:命宮主星 + 各主題宮位主星)。依星座 → 紫微斗數的順序接在各主題的八字段落之後。省略或為 [] 時,回應與現在完全相同 | |
calendar · isLeapMonth | string · boolean | 為 "lunar" 時,會把 year、month、day 當作農曆,轉換成國曆後計算(預設 "solar")。isLeapMonth: true 代表閏月,若該年沒有該閏月,會回傳 400 INVALID_LUNAR_DATE(2026-10-12 起)。以農曆傳送時,回應會附上 lunarInput(與萬年曆 API 相同格式) | |
birthLatitude · birthLongitude | number | 出生地座標(兩者一起傳送)。八字段落與 layers 以相同基準做真太陽時校正。標準子午線依 timezone 的標準時間(不含日光節約時間)決定。上升星座需要同時有出生時刻與座標才會出現 | |
country | string | 出生國家的 2 字母代碼。未帶座標而傳送 KR、JP、TH 時,以該國代表經度校正(其他國家不校正)。layers 也使用此國家(省略時依 lang 推估) | |
zaSiRule | string | 子時(23 點以後)的日柱:"traditional"(預設,取隔天日柱)、"yajaSi"(夜子時,取當天日柱;地點校正後 23 點時段的時柱天干以隔天日干為準,2026-10-20 起)。只用於八字段落(紫微斗數固定自 23 點起算隔天) | |
birthTimePrecision | string | exact、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 | 代碼 | 發生時機 |
|---|---|---|
| 404 | lifetime_not_enabled | 帳號未開通此功能 |
| 400 | INVALID_LUNAR_DATE · INVALID_LOCATION | 不存在的農曆日期/只傳送緯度、經度其中之一 |
| 402 | INSUFFICIENT_BALANCE | 以包含所請求層的金額事先確認時餘額不足 |
| 503 | lifetime_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 · day | number | O | 出生年(1900-2100)、月、日 |
hour | number | O | 出生時(0-23)。紫微斗數沒有出生時刻就無法排出命盤,省略時回傳 400 birth_time_required |
minute | number | 出生分(0-59),省略時為 0 | |
gender | string | O | "male" 或 "female"(決定大限的行進方向) |
calendar | string | solar(預設)或 lunar | |
isLeapMonth | boolean | 農曆閏月時為 true。國曆輸入時忽略。若該年沒有該閏月,會以平月計算,chart.lunarDate.isLeapMonth 回傳 false | |
birthTimePrecision | string | exact(真太陽時校正)或 approximate(不校正 + notes.approximateTimeNote)。省略時不校正 | |
birthLatitude · birthLongitude | number | 出生地座標(用於 exact 校正) | |
countryCode | string | 出生國家 ISO 2 碼,僅限大寫(例:KR,kr 會回傳 400)。沒有座標時以代表經度校正 | |
birthTimezoneOffset | number | 出生時刻的 UTC 偏移(分鐘,540 = KST) | |
referenceDate | string | 大限、流年基準日 YYYY-MM-DD(預設:今天,韓國時間) | |
lang | string | ko(預設)、en、ja、th | |
timezone | string | 為了與萬年曆 API 相容(不用於計算,因此即使是無法辨識的名稱也不會附上警告) | |
readings | boolean | 為 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(帳號未開通此功能)、404ziwei_readings_not_enabled(未開通解讀段落)、503ziwei_readings_unavailable(無法讀取解讀段落)。
錯誤代碼
除了共通錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 404 | ziwei_not_enabled | 帳號未開通此功能 |
| 404 | ziwei_readings_not_enabled | 為 readings: true 但未開通解讀段落 |
| 400 | invalid_birth_date | 不存在的國曆日期,或農曆日、閏月超出範圍 |
| 400 | birth_time_required | 沒有 hour,會如上方範例一併回傳 partial |
| 400 | reference_date_before_birth | referenceDate 早於出生日期 |
| 402 | INSUFFICIENT_BALANCE | 餘額不足 |
| 503 | ziwei_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/次(僅在帳號已開通時,未開通時回傳 404identity_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 | 代碼 | 發生時機 |
|---|---|---|
| 404 | identity_not_enabled | 帳號未開通 |
| 400 | INVALID_LUNAR_DATE · INVALID_LOCATION | 不存在的農曆日期/只傳送緯度、經度其中之一 |
| 402 | INSUFFICIENT_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 的整數、未知的鍵 |
| 400 | INVALID_LUNAR_DATE · INVALID_LOCATION | 不存在的農曆日期/只傳送緯度、經度其中之一 |
| 402 | INSUFFICIENT_BALANCE | 餘額不足 |
| 404 | saju_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。另外還接受:
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
date | string | 要查看的日期 YYYY-MM-DD(1900-2100)。省略時為韓國時間的今天 | |
temperatureC | number | 目前氣溫(℃,−40~50)。傳送時回應會附上 fashion(早·午·晚穿搭)。省略時沒有 fashion(不做推估) | |
weather | string | 天氣:clear · cloudy · rain · snow · storm | |
humidity | number | 相對濕度(%,0~100)。必須同時傳送 temperatureC·weather·humidity 三個值,才會附上 fashion.mood(各時段一句天氣評語) | |
mbtiBehavior | boolean | 為 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 | 代碼 | 發生時機 |
|---|---|---|
| 404 | today_not_enabled | 帳號尚未開通此功能 |
| 400 | INVALID_LUNAR_DATE · INVALID_LOCATION | 不存在的農曆日期 / 緯度·經度只傳送其中一個 |
| 402 | INSUFFICIENT_BALANCE | 餘額不足 |
解夢 API
POST /api/v1/partners/v1/dream
從終端使用者描述的夢境中找出象徵詞(例:大海、魚),並依顯著程度排序回傳。詞語取自 HRUM 自行編製的夢境象徵詞庫(約 1,000 個日常名詞及其同義詞·活用形·口語說法)。詞庫只收錄詞語,不含解夢意義或吉凶判斷。回傳的詞語都是該詞或其同義詞·活用形實際出現在夢境內容中的。
請求參數
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
dream | string | ✓ | 夢境內容(最多 1,000 字) |
feeling | string | 夢中的感受(最多 300 字,例:「무섭고 답답했어요」—「又害怕又悶」)。與夢境內容合併後擷取標籤(合併後最多使用 1,000 字) | |
lang | string | 回應語言。目前僅支援 ko(詞典僅有韓文)。其他值回傳 400 | |
includeNegative | boolean | 古籍依據中是否也納入凶的判斷(死亡、疾病、失去等)紀錄。預設 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 | 代碼 | 發生時機 |
|---|---|---|
| 404 | dream_not_enabled | 帳號尚未開通此功能 |
| 402 | INSUFFICIENT_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, modelVersion | string | ✓ | 產生座標的模型。不在允許清單內時回傳 400 MEASURE_MODEL_UNSUPPORTED / MEASURE_MODEL_VERSION_MISMATCH。目前:face_landmarker · float16/[email protected] |
normalization | string | ✓ | face-norm-1 |
landmarks | number[][] | ✓ | 正好 478 個 [x, y] 或 [x, y, z](除以影像寬·高的值,−0.02~1.02) |
imageWidth, imageHeight | number | ✓ | 像素尺寸 |
hairline | [number, number] | 臉部中央髮際線的一點。伺服器不做推估 — 沒有時上停相關的鍵為 null(原因 hairline_missing)。建議讓使用者點選額頭上方頭髮開始的位置(頭髮分割模型僅供參考) | |
quality | object | yawDeg·pitchDeg·rollDeg·blendshapes(MediaPipe 係數名稱→分數)。必須傳送才會進行品質檢查 | |
includeNegative | boolean | 是否也納入凶的判斷紀錄(polarity negative)。預設 false(與解夢相同的名稱·意義) |
POST /api/v1/partners/v1/palm-measure
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
modelName, modelVersion | string | ✓ | 目前:hand_landmarker · float16/[email protected] |
normalization | string | ✓ | palm-norm-1 |
landmarks | number[][] | ✓ | 正好 21 個 |
imageWidth, imageHeight | number | ✓ | 像素尺寸 |
handedness | string | ✓ | left | right — 被拍攝者實際的手(請讓使用者選擇) |
mirrored | boolean | 左右翻轉的照片(自拍預覽)時為 true | |
creases | object[] | 手相線折線(最多 64 條,每條 2~512 點)。欄位:points(✓)、label(life·head·heart·fate·sun·mercury·simian·unknown)、kind(segment | branch)、autoLabel。沒有時線相關的鍵為 null(creases_missing) | |
autoLabel | boolean | 以伺服器共用的啟發式規則為所有未命名的線命名。若只要用於某一條線,請在該項目指定 autoLabel。自行指定的 label 永遠優先 | |
includeNegative | boolean | 與臉部相同。預設 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 | 代碼 | 意義 |
|---|---|---|
| 400 | MEASURE_MODEL_UNSUPPORTED | modelName 不在允許清單內 |
| 400 | MEASURE_MODEL_VERSION_MISMATCH | modelVersion 不在允許清單內(目前僅 float16/[email protected]) |
| 400 | MEASURE_NORMALIZATION_MISMATCH | normalization 不是 face-norm-1 / palm-norm-1 |
| 400 | MEASURE_LANDMARK_COUNT | 座標數量不是臉部 478 / 手部 21 |
| 400 | MEASURE_LANDMARK_SHAPE · MEASURE_COORD_NAN · MEASURE_COORD_RANGE · MEASURE_IMAGE_SIZE · MEASURE_DEGENERATE | 點的格式·數值·範圍(−0.02~1.02)·影像尺寸錯誤 |
| 400 | MEASURE_HANDEDNESS · MEASURE_CREASE_LIMIT · MEASURE_CREASE_SHAPE · MEASURE_CREASE_LABEL | 手部·手相線輸入錯誤 |
| 400 | MEASURE_QUALITY_POSE · MEASURE_QUALITY_FACE_SIZE | 頭部轉動超過 10° · 臉部太小 — 請重新拍攝 |
| 400 | (驗證錯誤) | 傳送了文件中沒有的欄位 — 請只傳送允許的欄位 |
| 402 | INSUFFICIENT_BALANCE | 點數餘額不足 |
| 404 | face_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
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
image | object | 二擇一 | { data, mimeType } — data 為照片位元組的 base64(解碼後最多 8MB),mimeType 為 image/jpeg · image/png · image/webp。格式會再以位元組確認(不符則回傳 400) |
landmarks | object | 二擇一 | 與面相測量請求本文相同(modelName · modelVersion · normalization · landmarks 478 點 · imageWidth · imageHeight · hairline · quality · includeNegative) |
consent | object | 照片時 ✓ | 照片處理同意 — 請見下方同意物件 |
llm | boolean | 不必傳送 — 一律包含 AI 解讀。傳送 false 會回傳 400 USE_FACE_MEASURE(不含 AI 的測量請用面相測量) | |
lang | string | 接受 ko · en · ja · th,但解讀文字目前僅有韓文(回應的 lang = "ko") | |
endUserId | string | 合作夥伴使用的終端使用者 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
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
image | object | ✓ | 一張手掌面的照片。格式·大小與面相相同 |
consent | object | ✓ | 同意物件 |
creases | object[] | 使用者在照片上描繪的手相線(最多 16 條)。欄位:line(life · head · heart · fate · sun · mercury · simian · unknown)、points([x, y] 2~256 個,以照片左上角為基準的 0~1)。尋找線的位置時會優先參考 | |
lang | string | 與面相相同(解讀文字目前僅有韓文) | |
endUserId | string | 與面相相同 |
請求範例(手相,含描繪的線)
{
"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
例:"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)。手背照片回傳 400PALM_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 | 代碼 | 意義 |
|---|---|---|
| 400 | READING_INPUT_ONE_OF | 面相:image 與 landmarks 不是正好只有一個 |
| 400 | IMAGE_REQUIRED | 手相:沒有 image |
| 400 | CONSENT_REQUIRED | 傳送照片但沒有 consent 或值不正確 |
| 400 | IMAGE_INVALID · IMAGE_FORMAT_UNSUPPORTED | 無法讀取的照片 · mimeType 與實際格式不同 · 不是 JPEG·PNG·WebP(含動態 WebP) |
| 413 | IMAGE_TOO_LARGE | 照片超過 8MB · 超過 8192px 或 1680 萬像素 · WebP 長邊超過 1600px |
| 400 | IMAGE_NOT_ALLOWED | 看起來未成年 · 多張臉 / 兩隻以上的手 · 不是臉部·手掌照片 |
| 400 | FACE_NOT_DETECTED · PALM_NOT_DETECTED | 找不到臉部 / 手掌(手背照片為 PALM_NOT_DETECTED) |
| 400 | USE_FACE_MEASURE | 面相 landmarks 搭配 llm: false — 不含 AI 的測量請用面相測量 API |
| 400 | MEASURE_LOW_QUALITY | 模糊 · 太暗 · 被遮住 · 太小 · 傾斜 — 原因列於回應的 quality。請引導使用者重新拍攝 |
| 400 | CREASE_INVALID | 手相線的點少於 2 個或超出 0~1 範圍 |
| 400 | MEASURE_* | landmarks 輸入錯誤(與面相測量相同的代碼) |
| 402 | INSUFFICIENT_BALANCE | 餘額不足 — 在呼叫外部模型前確認 |
| 404 | face_reading_not_enabled · palm_reading_not_enabled | 尚未開放的功能 |
| 409 | IDEMPOTENCY_KEY_REUSED · IDEMPOTENCY_IN_PROGRESS | 同一個 X-Idempotency-Key 用於不同本文 · 同一金鑰的第一個請求仍在處理中(請見下方重試與重新傳送) |
| 429 | FILTERED_QUOTA_EXCEEDED | 今日被過濾的照片已達每日上限 — 請見下方被過濾照片的每日上限 |
| 502 | READING_UNAVAILABLE | 無法產生解讀(含輸出被截斷的情況) — 請重試 |
| 503 | IMAGE_BUSY | 照片處理繁忙 — 請稍後再試 |
| 504 | LLM_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.hangul | string | ✓ | 2~6 個音節的韓文姓名,姓氏在前(例:김하늘)。남궁(南宮)、황보(皇甫)、제갈(諸葛)、선우(鮮于)、독고(獨孤)、사공(司空)、서문(西門)、동방(東方)視為兩字姓氏 |
name.hanja | (string|null)[] | 每個音節一個漢字,不知道則為 null。長度與音節數不同時回傳 400 NAME_HANJA_LENGTH | |
name.strokes | (number|null)[] | 每個音節的原筆畫數(以原字為準)(1~64),不知道則為 null(見下方筆畫數說明) | |
name.meanings | (string|null)[] | 每個音節的漢字字義(訓,例:물(水)· 쇠(金屬),1~20 字)。字源五行只依此字義判斷 | |
birth | object | { year, month, day, hour?, minute?, gender?, timezone? }(國曆)。傳送時會計算八字用神,查看姓名是否補足該五行。timezone 預設 Asia/Seoul。出生年月日不會傳送給外部模型 | |
interpret | boolean | 預設 true(姓名解讀)。false 時僅做姓名計算(不含 AI) | |
echoName | boolean | 2026-10-31 新增。預設 true(與目前相同)。false 時回應中任何地方都不再寫出姓名文字 — name 為 null,deterministic.syllables 的 hangul·hanja·meaning 為 null,改附上 position(從 1 開始)。items 中的文字標示也會改為「첫 글자(목(木))」(「第一個字(木(木))」)這樣的位置表示;若為姓名解讀,姓名本身不會傳送給 AI(只傳送計算值與位置) | |
consent | object | 姓名解讀時 ✓ | { "version": "name-consent-2026-10", "subject": "end_user" } — version 為合作夥伴顯示的同意文字版本(1~40 字),subject 為 end_user · third_party。沒有或值不正確時回傳 400 CONSENT_REQUIRED。用量紀錄只會留下 version 與 subject。interpret: false 時不需要 |
lang | string | 接受 ko · en · ja · th,但目前只以韓文回答 | |
endUserId | string | 合作夥伴的終端使用者 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 | 代碼 | 意義 |
|---|---|---|
| 400 | NAME_INVALID | 韓文姓名不是 2~6 個音節 · hanja/strokes/meanings 值的格式錯誤 |
| 400 | NAME_HANJA_LENGTH | hanja 長度與音節數不同 |
| 400 | CONSENT_REQUIRED | 姓名解讀但沒有 consent 或值不正確 |
| 400 | (驗證錯誤) | 不存在的日期 · 文件中沒有的欄位 |
| 402 | INSUFFICIENT_BALANCE | 餘額不足 |
| 404 | naming_not_enabled | 尚未開放的功能(姓名解讀·姓名計算分別開放) |
| 409 | IDEMPOTENCY_KEY_REUSED · IDEMPOTENCY_IN_PROGRESS | 同一個 X-Idempotency-Key 用於不同本文 · 同一金鑰的第一個請求仍在處理中(請見下方重試與重新傳送) |
| 502 | READING_UNAVAILABLE | 無法產生 AI 解讀 — 不計費(也沒有只回傳計算結果的部分計費)。請重試 |
| 504 | LLM_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 解讀 — 牌義就是該牌固定的文字。因此使用方式有三種。
- 只呼叫塔羅來做應用程式 — 將回應中的牌名·牌義·圖片直接繪製在畫面上。
- 塔羅 + LLM 解讀 — 將抽出的牌傳入 LLM API,自行撰寫解讀。
- 與八字 AI 組合 — 在 AI 八字解讀請求中加入
tarot,就會連同八字解讀一起解讀塔羅(包含項目)。
請求參數
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
count | number | △ | 要抽的張數 1~10(整數)。count 與 spread 只能傳送其中一個。兩者都傳或都沒傳時回傳 400 |
spread | string | △ | 牌陣。張數與位置名稱都是固定的:single(今日一張,1 張)· past-present-future(過去·現在·未來,3 張)· choice(選擇:目前狀況·阻礙·結果,3 張)· celtic-condensed(凱爾特簡化版,5 張)· future-prediction(未來預測,5 張) |
reversed | boolean | 是否允許逆位(預設 true)。false 時全部為正位 | |
seed | string | 用於重現的字串(1~200 字)。相同 seed + 相同 count/spread + 相同 reversed 時,永遠抽出相同的牌。沒有時每次隨機(密碼學亂數) | |
question | string | 終端使用者的問題(最多 500 字)。不用於解讀,會原樣回傳於回應中 — 這是為了方便傳給下一個 LLM 步驟而設的欄位 | |
lang | string | 牌名·關鍵字·牌義·牌陣名稱的語言: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
}
}
cards[]:position(從 1 開始,抽牌順序 = 牌陣位置)·positionLabel(牌陣位置名稱,以count抽牌時為null)·id(與語言無關的牌卡唯一值)·name(請求的語言)·nameEn·arcana(major|wands|cups|swords|pentacles)·reversed·keywords·meaning(抽出方向的內容)·imageUrl。spread:以count抽牌時為null。- 牌卡圖片:
imageUrl·cardBackUrl為 WebP(寬 600px),網址中含有版本(v2),因此不會變動 — 可以下載後快取並直接使用。逆位的牌請將圖片旋轉 180 度顯示(圖片本身只有正位一張)。 - 圖片來源:1909 年 Rider-Waite(Pamela Colman Smith,公共領域)原版掃描。78 張牌與牌背皆為 Wikimedia Commons 上的 1909 年原版掃描,各檔案的來源·授權請見來源清冊。舊網址(
v1)也會回傳相同的圖片,因此不需要更改已儲存的網址。 costPoints:本次呼叫的扣款金額(₩)。
價格
- 每次呼叫固定價格 — 抽 1 張或 10 張都一樣。價格請見價格中的計算型表格。僅成功的呼叫計費,相同輸入的重複呼叫也會各自計費(冪等性)。
- 輸入錯誤(400)、餘額不足(402)不計費。用量紀錄的 endpoint 為
tarot。 - 在尚未開放的狀態下呼叫時回傳 404
tarot_not_enabled(不計費)。
Waite 原典依據 kb
開放後回應會附上 kb。針對每張抽出的牌,從 A. E. Waite《The Pictorial Key to the Tarot》(1910 年,公共領域)原文中,以規則 ID(R-TAROT-*)與原文引用回傳該牌的正位·逆位牌義。上方的 meaning·keywords 維持不變,只會多加 kb,價格相同。
kb.cards[]:position·id·reversed·drawn(抽出方向的牌義)·upright·reversedMeaning·positionRule。每個牌義含ruleId·status·statement(韓文)·quotes[](quote英文原文、location章節、foundAt原文行)·variants[](Waite 記載的其他說明alternative、第三部 §4 的附加意義additional)。status直接沿用 KB 的標示(verified= 有原文引用)。Waite 未記載牌義的位置(聖杯二逆位)為ruleId: null、status: "disputed"。method: "celtic-cross":Waite 在書中記載的凱爾特式占卜法(10 張)。用來取代count·spread傳送,10 個位置各自的 Waite 位置意義會放在positionRule。其他spread是 Waite 原文中沒有的排列,因此沒有位置依據(kb.method: null)。kb.caveats:Waite 所說牌義會隨位置改變的說明,以及使用原則(是占卜的工具,不能取代健康·法律·財務方面的決定)。- 開放前傳送
method時回傳 404tarot_kb_not_enabled(不計費)。
{
"method": "celtic-cross",
"seed": "user-1042:2026-10-11"
}
錯誤代碼
除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 404 | tarot_not_enabled | 帳號尚未開通此功能 |
| 404 | tarot_kb_not_enabled | 傳送了 method,但原典依據尚未開放 |
| 402 | INSUFFICIENT_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(不計費)。
注意事項
- 價格:₩20 / 次呼叫(依量計費) ·
readings: true時另加 ₩20(合計 ₩40) - 日期驗證:錯誤的日期(例:2 月 30 日)或錯誤的座標/時區會回傳 400 錯誤,且不計費。
- 上升星座計算:需要出生時刻 +
birthTimePrecision(exact/approximate,省略則為exact)+ 緯度/經度全部齊備。缺少任何一項時ascendant為null。 - 解讀段落錯誤:
readings: true但帳號未開通時回傳 404natal_readings_not_enabled,無法載入段落時回傳 503natal_readings_unavailable— 兩者皆不計費。 - 太陽/月亮/上升星座:所有行星與軸點皆以回歸黃道(西洋占星標準)為準。
- 2026-10-17 變更(
engineVersionnatal-2):傳送birthTime而省略birthTimePrecision時,現在會以該時刻計算(以前會忽略時刻而以正午計算,上升星座為null)。與其他 endpoint 的規則相同。沒有birthTime或直接傳送精確度的呼叫,結果維持不變。
錯誤代碼
除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 404 | natal_readings_not_enabled | readings: true 但解讀段落尚未開通 |
| 503 | natal_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(以正午為準)。
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
houseSystems | string[] | 從 placidus · whole_sign · equal · porphyry 中選擇。省略時為 ["placidus"]。出生地位於極圈內(緯度約 66.56° 以上,angles.polar)時,會以 Porphyry 取代 Placidus 計算,並在結果附上 "fallbackFrom": "placidus"(直接指定 Placidus 時也相同) | |
minorAspects | boolean | 納入十二分之一相(30°)·半四分相(45°)·八分之三相(135°)·十二分之五相(150°)(本命盤·合盤比較)。預設 false — 僅 5 種主要相位 | |
orbs | string | 本命盤·合盤比較的容許度表:leo1928(預設 — 合相·對分相 日–月 12°、日/月–行星 10°、行星之間 8°,四分相·三分相 8°,六分相 7°,半四分相·八分之三相 4°,十二分之一相·十二分之五相 2°)· heindel1919(主要相位一律 6°,較保守) | |
node | string | 規則鍵中的 Nn(北交點)·Sn(南交點 = 北交點 + 180°)所依據的交點:mean(預設,平均交點)· true(真實交點)。適用於 features 的 node_sign Nn_…·Sn_… 與交點合相鍵(Mo_Nn_cj·Nn_Asc_cj 等)。MNn_…·TNn_… 鍵不論此值為何都會兩者皆回傳 | |
lang | string | signName(星座名稱)的語言 — ko(預設)· en · ja · th | |
timing | object | 傳送時會計算行運 + 次限推運,並放入回應的 timing。見下表 | |
partner | object | 對方的出生輸入(與上方相同的欄位,lang 除外)。傳送時會將兩人之間的相位·星座關係放入回應的 synastry。若有對方的出生時刻與座標(birthLatitude·birthLongitude),也會計算對方的上升點(Asc)·天頂(MC)並納入交叉相位 |
timing 區塊內容:
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
orbDegrees | number | O | 行運→本命、推運→本命相位的容許度(度)0.5~10。所有天體組合使用相同的值(僅 5 種主要相位) |
at | string | 要查看的時間點。YYYY-MM-DD(= 當天 00:00 UTC)或附上時差的日期時間(2026-10-11T09:00:00+09:00、...Z)。沒有時差的日期時間回傳 400。省略時為現在 | |
progressions | boolean | 計算次限推運(預設 true) | |
yearLength | string | 將經過時間換算為「人生第幾年」時使用的一年長度: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 鍵。
bodies[]:太陽·月亮·水星·金星·火星·木星·土星·天王星·海王星·冥王星。longitude為黃經(0° = 春分點,回歸黃道),speed為度/日 — 負數表示retrograde: true。每顆天體都直接附上signName(lang語言的星座名稱)·degreeInSign(星座內度數 0~30°)·house(依請求的宮制分別列出宮位編號,與houses[system].bodies相同的值 — 未計算宮位時為{}),光靠這些就能繪製星盤表格。dignities:太陽~土星的品位(dom本垣 ·exa擢升 ·det失勢 ·fal落陷,列出所有符合的狀態)。與bodies[].dignities為相同的值。nodes[]:MeanNode(平均交點)·TrueNode(真實交點)= 北交點,south= 南交點(+180°)。angles:ASC·MC·DSC·IC。僅在出生時刻(exact/approximate)與座標兩者皆有時計算。否則為null,並由anglesOmitted告知原因(time_unknown|coordinates_missing)。此時也不計算宮位,houses為{}。houses:依請求的宮制分別列出cusps(第 1~12 宮起始黃經)+bodies(各天體的宮位編號)。houseSystems·houses:實際計算的宮制。出生地位於極圈內(angles.polar= 緯度約 66.56° 以上)時,Placidus 可能無法定義,因此改以 Porphyry 計算,並以houses.porphyry.fallbackFrom = "placidus"標示(不會暗中替換)。判定依出生地緯度,因此同一出生地不論時刻都會得到相同的宮制。housesExcluded是其他無法計算的宮制及其原因(並非錯誤回應)。aspects[]:orb= 偏離正相位的度數,strength=exact(2° 以內)·close(上限的一半以內)·wide,applying= 正在接近正相位時為true(不明則為null),outOfSign= 跨越星座邊界的相位(解讀時減弱一級)。moonSignUncertain:時刻不詳且當天內月亮星座改變時為true— 此時features中月亮的planet_sign會附上"uncertain": true。readings(一律包含,不另收費):HRUM 預先寫好的解讀段落。dignities[]= 品位(太陽~土星,每顆天體取最強的一個狀態),aspects[]= 本命天體之間的相位,依容許度由小到大排列。每個段落含key(與features·aspects[].key相同的鍵)·text·lang(段落實際語言 — 沒有請求語言的段落時為ko)·deviation(僅相位,偏離正相位的度數)。只有已預先寫好段落的鍵才會附上,其餘略過(不會即時編寫)— 涉及天王星·海王星·冥王星的相位與次要相位沒有段落,因此不包含。沒有出生時刻時,涉及月亮的相位不附上;月亮星座不確定時,月亮品位不附上。上方範例(1990-05-15 14:30 首爾)為 16 個相位中的 7 個 + 品位 4 個 = 11 個段落。readingsUnavailable:無法載入解讀段落時為true— 此時星盤計算結果仍照常回傳,readings為空陣列,價格(₩50)也不變。features[]:用於比對規則資料庫的鍵。planet_signSu_ari·planet_retrogradeMe_rx·dignityMa_dom·node_signMNn_leo·TNn_leo·Nn_leo·Sn_aqu(Nn·Sn為node選項所選的交點)·angle_signAsc_sco·planet_houseVe_h7(+system)·aspectSu_Mo_cj(交點只算合相 3° —Mo_Nn_cj·Sa_Sn_cj·Nn_Asc_cj,與上升點的組合僅在有出生時刻時)·house_cusp_signh12_ari(第 12 宮宮首在牡羊座)·house_emptyh6(10 顆行星都不在的宮位)·house_ruler_househ1_h7(第 1 宮宮主星在第 7 宮)·house_ruler_signh7_lib(第 7 宮宮主星在天秤座)— 宮主星為宮首星座的傳統守護星(太陽~土星 7 顆行星)·planet_risingJu(第 1 宮,或在第 12 宮且距上升點 6° 以內)— 這五類會附上+system,僅在有出生時刻與座標時出現 ·planet_solarVe_cazimi(距太陽 17′ 以內)/Me_combust(17′~8°30′,與太陽同星座)/Ma_beams(其餘 17° 以內)— 三個階段不重疊 ·moon_phasewaxing·waning·metatime_known(有時刻 —exact·approximate)/time_hour_level(approximate時追加)/time_unknown。相位類鍵(aspect·transit·progressed·syn_aspect)會附上orb(偏離正相位的度數,小數點後兩位),且僅在相位跨越星座邊界時附上"outOfSign": true— 這是用來對應規則鍵屬性[orb=…]·[outOfSign=true]的值。出生時刻不詳時,涉及月亮的本命相位會附上"uncertain": true。天體縮寫Su Mo Me Ve Ma Ju Sa Ur Ne Pl,交點MNn TNn Nn Sn,相位代碼cj(0°)sx(60°)sq(90°)tr(120°)op(180°)· 次要ssx(30°)ssq(45°)sqq(135°)qcx(150°)。
請求範例 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
}
}
- 行運對象(
natalPoints):本命天體 10 顆 + 有出生時刻·座標時的上升點(Asc)·天頂(MC)。鍵使用t(行運)·n(本命)前綴 —tSa_nSu_cj= 行運土星與本命太陽合相。 transit_housetSa_h7(行運土星在本命第 7 宮)·progressed_housepMo_h4(推運月亮在本命第 4 宮):各 10 顆行星。本命宮位使用預設宮制(Placidus,極圈內則為 Porphyry +"fallbackFrom": "placidus"),鍵會附上"system"— 即使傳送不同的houseSystems,這兩種鍵仍以預設宮制為準。沒有出生時刻或座標時不會出現。- 推運→本命相位只以本命行星為對象。鍵
pSu_nJu_tr= 推運太陽與本命木星三分相。instant是作為推運盤所用天空的時刻(出生 +ageYears日)。 progressions: false時timing.progressions為null。省略yearLength時為tropical(365.24219 日)。- 在
progressions開啟的狀態下,timing.at早於出生時刻時回傳 400at_before_birth(不計費)。 - 時刻不詳時,本命盤以正午為準。以本命月亮為對象的鍵(
…_nMo_…)與推運月亮鍵(pMo_…)會附上"uncertain": true(推運月亮直接承接本命月亮的位置,因此會隨正午假設而有所偏差)。
請求範例 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
}
}
- 鍵前綴
a= 發出請求的本人,b=partner。aVe_bMa_cj= 本人金星與對方火星合相。檢視本人 10 顆天體(+上升點·天頂)× 對方 10 顆天體(+上升點·天頂)的所有組合(有方向性,因此aSu_bMo與aMo_bSu是不同的鍵)。 - 上升點(
Asc)·天頂(MC)僅在該人的出生時刻與座標兩者皆有時計算(與本人相同的規則,對方見synastry.partner.angles/anglesOmitted)。涉及軸點的交叉相位只看合相·對分相,容許度 6°。唯有上升點之間的合相(aAsc_bAsc_cj)放寬到 17°(托勒密《四書》— 兩人的上升點在 17° 以內則連結強烈,規則[orb=17])。實際相距的度數放在orb。軸點只要擁有該軸點者的時刻確定即可計算。下降點·天底是上升點·天頂的正對面,因此不另設鍵。 astro_syn:古典 6 組(太陽–月亮、金星–火星、月亮–金星、太陽–金星、月亮–火星、金星–土星)的星座關係中最強的 2 個。兩個方向合併為一個鍵(Su_Mo_se= 一方的太陽與另一方的月亮為同元素)。syn_sign:本人所有點 × 對方所有點的星座關係(aAsc_bAsc_ss)。兩人的出生時刻都是exact時,幸運點(PoF,日夜公式反轉)也納入點中(aPoF_bPoF_ss)— 幸運點與上升點一起約每 4 分鐘移動 1°,因此以時辰為單位(approximate)或時刻不詳時不產生。關係代碼ss(同星座)·op(對宮星座)·se(同元素)·es(元素相助)·sm(同模式)·ef(元素摩擦)·nt(無關)。- 容許度表與是否納入次要相位,使用與本命盤相同的
orbs·minorAspects。由於是兩張本命盤之間的比較,沒有入相·出相之分,因此applying一律為null。 - 只要任一方的出生時刻不詳,該人的星盤就以正午為準。涉及該人月亮的相位會在
features附上"uncertain": true(月亮一天約移動 13°,變動範圍大於容許度)。與對方軸點配對的相位(aAsc_bMo_…,反方向aMo_bAsc_…)也相同。 - 不計算對方的宮位(不提供合盤宮位疊加)。
預設值與必須自行選擇的值
- 宮制(預設
placidus):1819 年·1929 年辭典記載為「通用」的宮制。出生地位於極圈內時以 Porphyry 替代,並以fallbackFrom標示。需要其他宮制時請以houseSystems選擇。 - 推運一年的長度(預設
tropical365.24219 日):原典所說「生日→下一個生日」的一年。與儒略年(julian)的差異,在 80 歲時約為推運時刻 2.5 分鐘。 - 行運·推運容許度(
timing.orbDegrees,傳送timing時為必填):各原典不一(正相位前 8° 至 10° 的區間)。留空時回傳 400。 - 涉及冥王星·交點·軸點的本命相位不在預設容許度表中:這些是 Leo(1928)·Heindel(1919)容許度表未涵蓋的點(冥王星於 1930 年發現)。因此本命
aspects中不會出現這些點(位置·宮位中會出現)。只有合盤比較中的軸點交叉相位以合相·對分相 6°(僅上升點之間的合相為 17°)檢視。
不提供的項目
- 次要品位(三分性 triplicity·界 term·外觀 face)、互容(reception)、本命幸運點(僅用於合盤比較的
syn_sign)、天王星·海王星·冥王星的品位、平行相位·中點 - 推運軸點(推運 ASC·MC)— 原典未訂定方法
- DSC·IC 提供數值,但不產生
features鍵(南交點以Sn鍵產生) - 新月·滿月·上弦·下弦的月相鍵(
moon_phase只有waxing·waning)、相對太陽的東方·西方(oriental·occidental)、推運軸點鍵 - 合盤宮位疊加
價格
- 與萬年曆相同,每次 ₩50 — 即使加上
timing·partner區塊,不論宮制·是否納入次要相位,都是同樣一次 ₩50。回應的costPoints為本次扣款金額(₩)。用量紀錄的 endpoint 為astrology。 - 僅在計算成功時扣款。輸入錯誤(400)、餘額不足(402)不計費。
- 在尚未開放的狀態下呼叫時回傳 404
astrology_not_enabled(不計費)。
錯誤代碼
除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 404 | astrology_not_enabled | 帳號尚未開通此功能 |
| 400 | at_before_birth | timing.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
| 參數 | 型別 | 必填 | 說明 |
|---|---|---|---|
birthDate | string | O | YYYY-MM-DD(1900~2100)。以 calendar 為準的日期 |
birthTime | string | null | HH:mm。沒有時為時柱不詳 — 以六個字計算,hourKnown: false | |
calendar | string | O | solar · lunar(農曆會換算為國曆後計算) |
isLeapMonth | boolean | 農曆閏月(預設 false) | |
gender | string | null | male · female。沒有時不含大運層(daeun: [],daeunIndex: null) | |
timezone | string | 僅接受 Asia/Seoul | |
birthLatitude · birthLongitude | number | 出生地座標(必須兩者皆傳)。與萬年曆 API相同的欄位·相同的規則 — 以經度進行真太陽時校正,運勢走勢也繪製在萬年曆回傳的校正後命盤上。只傳其中一個時回傳 400 INVALID_LOCATION。不傳送時依循萬年曆的預設處理(目前為不校正),並以 assumedLocation 告知 | |
country | string | 出生國家的 2 字母代碼。不帶座標傳送 KR·JP·TH 時,以該國的代表經度校正(與萬年曆相同) | |
birthTimePrecision | string | exact · approximate · estimated · unknown。僅在 exact 時校正(傳送位置時預設為 exact)。傳送 exact 以外的值時,不做真太陽時校正。韓國夏令時間期間出生者,與萬年曆相同,減去 1 小時以標準時讀取(2026-10-16) | |
range | object | O | { "fromYear", "toYear" } 流年範圍(國曆年份,最多 101 年)。建議一次取得出生年 ~ 出生年+100,再於畫面上擷取使用 |
monthsOfYear | integer | null | 要計算流月 12 格的八字年份(當年立春起至隔年立春前)。省略時為目前(韓國時間)所屬的八字年份 — 1 月 1 日~立春前為前一年。null 時不含流月層(months: []) | |
lang | string | ko · 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
}
}
欄位閱讀方式
line:累積值 — 大運為命盤 + 大運,流年為命盤 + 當年大運 + 流年。每個階段截斷在 ±100,被截斷時為clamped: true(R-SAJU-UN-033)。流月沒有累積線,只提供該月運勢的分數(delta)。share:單一干支分數的拆解(生扶·剋洩·藏干·通根)。各層權重為大運·流年·流月 1:1:1(R-SAJU-UN-030),運勢地支的通根沒有上限(R-SAJU-UN-031)。shinRole:該干支五行的五神名稱(用神·喜神·忌神·仇神·閑神,R-SAJU-YONG-170)— 是名稱而非分數。所有命盤都會附上五神表(不會是null)。relations:運勢干支與命盤干支之間的刑沖會合清單(不計入分數)。ruleId是配對表規則,decisionRuleId是同樣適用於運勢的依據規則(UN-035 流月、UN-036 自刑、UN-037 半合)。withDaeun為流年 ↔ 當年大運。時柱不詳時,不產生與時柱的關係。triples:大運·流年干支加入後,與命盤一起湊滿三合·方合三個字的情況(R-SAJU-UN-037)。hapPulim:大運·流年干支所觸動的命盤合(合起·解開·破壞)以及新結成的合(R-SAJU-HAP-021~027)。不含流月。畫面文字請依reasonCode與params(incoming進入的運勢干支、origindaeun|seun,必要時target·partner)配合應用程式語言自行組成。reasonFallback一律附有引擎撰寫的韓文句子,僅在應用程式收到不認識的reasonCode時作為替代顯示之用。reasonCode目前有 7 種。stem_hap_kept_jaenghap:命盤的天干合維持不變,相同陽干的運勢干支(incoming)因爭合而無法介入。stem_hap_kept_tuhap:命盤的天干合維持不變,相同陰干的運勢干支(incoming)因妒合而無法介入。branch_hap_gi:運勢干支(incoming)沖命盤六合中的一字(target),使合發動(合起)。branch_hap_released:運勢干支(incoming)刑命盤六合中的一字,使合解開。branch_hap_broken:與命盤六合中一字相同的字(incoming)以運勢進入,使合破壞。new_stem_hap:運勢天干(incoming)與命盤中未成合的天干(partner)結成新的天干合。new_branch_yukhap:運勢地支(incoming)與命盤地支(partner)結成新的六合。
startAge:大運數(第一步大運的年齡)。日數從出生日(韓國日期)0 時起算到交節為止,不計入出生的時·分,以 3 日 = 1 年四捨五入(R-SAJU-UN-038)。自kbVersion2026.10.11-2起收錄於規則清冊。ipchunNote:查詢時點(韓國時間)在當年立春之前時,僅今年的格為true。表示 1 月 1 日~立春前仍延續前一年的流年。流年採用當年立春的干支(R-SAJU-UN-016)。birthBeforeIpchun:於 1 月 1 日~立春前出生,命盤年柱為前一年干支時為true(最上層欄位)。assumedLocation(自saju-flow-5起,最上層欄位):未傳送位置時計算所用的預設值。目前與萬年曆相同,為{ "correction": "none" }(不做真太陽時校正)。萬年曆的預設值改為代表經度時,會回傳{ "correction": "trueSolarTime", "longitude": … }。有傳送位置(birthLatitude·birthLongitude或country)時為null。natalAmbiguous:時刻不詳且出生日有交節時為{ "pillar": "month" | "year", "termAt" }— 表示引擎以正午判定,月柱(若為立春則連年柱)可能與實際不同。compatInputs:多人疊加比較時,讓應用程式只需做集合交集的值(用神五行、外顯干支的五行數量、外顯中看不到的五行)。不提供人與人之間的加總·排名。
價格
- 銷售關閉時回傳 404
saju_flow_not_enabled(不計費)。 - 僅在計算成功時扣款。輸入錯誤(400 — 不存在的日期、範圍超過 101 年等)與 409 不計費。回應的
costPoints為本次扣款金額(₩),用量紀錄的 endpoint 為saju-flow。
錯誤代碼
除了通用錯誤(401、400 本文檢查、402、429、503 等)之外,此 API 會回傳的代碼:
| HTTP | 代碼 | 發生時機 |
|---|---|---|
| 404 | saju_flow_not_enabled | 帳號尚未開通此功能 |
| 400 | INVALID_DATE | birthDate 格式錯誤或不存在的日期 |
| 400 | INVALID_LUNAR_DATE | 不存在的農曆日期 |
| 400 | INVALID_RANGE | toYear 早於 fromYear,或超過 101 年 |
| 400 | INVALID_TIME | birthTime 不是 HH:mm 格式 |
| 400 | INVALID_LOCATION | birthLatitude·birthLongitude 只傳送其中一個 |
| 409 | saju_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 / personABirthLongitudepersonBBirthLatitude / 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 · personAIsLeapMonthpersonBCalendar · 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)。
- 時間校正:一個人的八字(日柱、八字分數、綜合分數、親密合盤符號表、生肖、權威分析、
yearFlow、關係描述)只計算一次,所有項目共用。未傳送座標、personXCountry、精確度exact時,以輸入時間原樣計算(與萬年曆 API 相同)。若需要與 INTA 應用程式(韓文、直接輸入時間)相同的合盤,請為兩人都傳送personXCountry: "KR"(+personXBirthTimePrecision: "exact")— 見下方建議呼叫。沒有出生時間的人不做校正。預設值(不傳送則不校正)不會改變。 - 2026-10-11 變更:傳送座標時,八字也會做真太陽時校正(之前只用於星座合盤)。這是為了讓同一回應中的八字與星座使用相同時間基準所做的修正,因此原本有傳送座標的呼叫,八字分數、日柱可能改變。新欄位以及未傳送座標的呼叫,回應維持不變。
- 日柱為代碼值:
saju.personA.ilju、saju.personB.ilju的值(계미等)不論lang為何,都以韓文干支代碼值輸出。畫面上要顯示的名稱,請改用萬年曆 API 的術語表(glossary)或漢字寫法(癸未,英文、泰文為癸未 (Gye-mi))。
建議呼叫(與 INTA 應用程式相同結果)
對知道出生時間的人,請一併傳送出生國家與 "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"
}
}
saju(八字合盤)是主體。少數無法計算日柱的情況為null— 此時只顯示ttisaju.score.total:0~100。日柱合盤表分數與八字分析分數的平均(各自在breakdown中)。grade是易懂的等級文字 — 아주 잘 맞아요(非常合,85 以上)、잘 맞아요(很合,75 以上)、무난해요(還可以,65 以上)、맞춰 가면 좋아요(互相配合會更好,55 以上)、서로 많이 달라요(彼此差異很大)。此值與以往相同 — 包含符號表、星座的分數是headerBreakdown.averagesaju.axes:吸引、穩定、成長、溝通、熱情、持久 6 軸(0~100),依purpose而異。saju.pattern:關係類型名稱與說明(無則為null)saju.iljuAxes(2026-10-27~):與 INTA 應用程式結果畫面 6 軸圖相同的值 — 直接採用兩人日柱組合在合盤表中的 6 軸(attraction、stability、growth、communication、passion、longevity,0~100,與purpose無關)。6 軸平均即headerBreakdown.sixAxis。鍵與saju.axes相同,但計算方式不同,數字也不同。合盤表中沒有該組合時為nullsaju.elements:以兩人整個命盤(不知時間則為 6 字 —basis: "six")的五行分布計算。bProvidesToA= A 缺少的五行中 B 擁有的部分saju.tenGods:以 A 為基準看 B 的十神(aView)及其反向(bView)。highlights:從八字中找到的交叉神煞句子(最多 5 句,無則為空陣列)relations(2026-10-16~):兩個命盤之間的關係清單。檢視同一位置的地支組合(年、月、日、時 — 時柱只在兩人都有出生時間時)、日干之間的天干合、天干沖、年柱納音五行,以及需合併兩個命盤才成立的三合、方合。每個項目有positions([A 方, B 方]—year、month、day、hour,三合、方合為chart= 整個命盤)、kind(見下表)、tier、ruleIds(依據的 KB 規則 ID — 可在 KB API 查看原典出處)、chars(關係字,漢字)。所有鍵都與語言無關,改變lang也相同。畫面文字請依kind自行製作。沒有好壞的判定詞。無法建立命盤時為null,完全沒有關係時為空陣列tier:gather聚合(合的一方)、clash相違、heavyClash重度相違(原典載明較重的關係,目前為沖)、listOnly僅列出(原典中找不到方向依據、不計入分數的關係)p2Score(2026-10-16~):0~100。將round(71.6 + 5 × Σ)截在 0~100 的值 — Σ = 每個關係依gather+1、clash−1、heavyClash−2、listOnly0 加總。1 單位 = 5 分,71.6 是完全沒有關係時的中立點(先前原典軸分數的實際會員平均,以 2026-10-16 為準)。有無時柱都使用相同尺度。原典只說明關係的方向與順位,未說明大小 — 這個數字是畫面顯示用的尺度假設,不是原典的分數(KBR-SAJU-COMPAT-113)。relations為null時為nullclassic1995(預計停止支援):目前仍與以往完全相同地回傳。停止時程(草案):2026-11-16 公告 → 維持至 2026-12-31 → 2027-01-01 起為null。日期可能依營運公告調整。新串接請使用relations、p2Score。參考文獻(1995)男女日柱親密合盤表的符號(●대길(大吉)100、◎중길(中吉)90、○길(吉)80、△무해무덕(無害無德)70、×흉(凶)60、××대흉(大凶)50)。此表是男方日柱 × 女方日柱的方向表,同性或未傳送性別時會讀取兩個方向(A 為男方、B 為男方),score為兩個分數的平均(例 95),symbol、grade則是將該平均以 10 分為單位無條件捨去後的等級(例 95 →◎중길)。兩個方向相同時直接使用該符號。conflictFrame:符號為吉但生肖關係為凶,或相反時為true。無法求得日柱時整體為nullastroSynastry:星座合盤。layers= 太陽、月亮、上升星座 3 層比較,purposeBodies= 依用途的優先行星(戀愛:金星、火星,婚姻:+土星,友情:水星、木星 …)。relation=same_sign、opposite、same_element、element_support、same_modality、element_friction、neutral,text是其含義解讀(lang)。score0~100。caveats/caveatTexts:上升星座、月亮星座為推估時說明此事。不知時間時會省略上升星座層astroReadings:針對兩人星座中最突出的交點(太陽–月亮、金星–火星等)最多 2 個,事先寫好的解讀段落。無則為空陣列。各段落的lang是實際文字語言(沒有請求語言的文字時為ko)headerBreakdown:將 6 軸平均、權威(authority)、八字(full8)、原典部分(classic— 自 2026-10-16 起為p2Score,之前為classic1995.score)、星座(natal)五個分數,依purpose別權重(weights)合併的綜合分數average(0~100)。缺少的分數由其餘分數重新分配權重。與 INTA 應用程式合盤畫面的代表分數(大數字)相同(上例為 62)。自 2026-10-16 起,婚姻用途(marriage_stability)的原典部分(classic)權重由 0.25 降為 0.05,減少的 0.20 依先前比例分給其餘四軸(sixAxis0.15 → 0.19、authority0.25 → 0.3167、full80.25 → 0.3167、natal0.10 → 0.1267)。其他用途的權重不變。找不到日柱合盤表時為null- 出生年份須在 1900~2100 — 超出範圍回傳 400
INVALID_BIRTH_YEAR(不計費)。在日期輸入欄位只輸入兩位數年份時會變成0090這樣,請在畫面上也加以阻擋。在合盤表中找不到結果時回傳 400COMPAT_UNAVAILABLE(不計費) tti.tier:參考文獻(1995)生肖合盤的等級字串(例:대길、길、중길、보통、주의、흉 — 從大吉到凶)。tti.relation.type= 兩個生肖地支的關係 —충(沖)、원진(怨嗔)、형(刑)、해(害)、육합(六合)、반합(半合)、파(破)其中之一(多個關係重疊時取此順序中較前者),無則為null。detail只在半合時出現(例:수국(水局))。tti.relation.relations= 所有重疊的關係(相同順序,例:牛、羊生肖["충","형"],無則為空陣列)tti只回傳生肖、關係、等級。不收錄參考文獻的生肖合盤文句(自 2026-10-11 起)。categoryNarrative:說明兩人在此關係(purpose)中狀況的 2~3 句話。這些是依兩人日柱組合(1,830 對)與 6 種關係類型事先寫好的句子,相同輸入永遠得到相同句子。句中的나= A,상대= B(英文You/Your partner,日文あなた/相手,泰文คุณ/คู่ของคุณ)。可透過lang選擇 4 種語言,找不到句子時為null(計費相同)- 必定包含(2026-10-10~):
saju.relationRatings= 5 種關係各自的{ key, stars }(key例:연애(戀愛)、결혼·동거(婚姻、同居)、친구(朋友)、사업 파트너(事業夥伴)、장기 관계(長期關係)/星等 1~5)、saju.meetingKeywords= 相遇關鍵字 3 個、saju.authority= 權威合盤判定(finalScore、grade、gradeTier、pattern、summary、levels(L1~L4)、factors、flags、climateBalance)、tti.conflictFrame= 與classic1995.conflictFrame相同的值 yearFlow.years[].tier:great、good、neutral、caution。dayFlow.days[].tier:golden、good、neutral、dim、hard(dayFlow.golden/hard為對應的日期清單)
關係類型(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 }, ... }
}
}
注意事項
- 基本資訊:兩人的出生日期為必填。時間與性別為選填。即使沒有性別或性別相同,也會提供親密合盤符號表(合計兩個方向);星座合盤的上升星座則需要出生時間。
- 結果組成:星座合盤以回歸黃道為準。各關係的描述以
categoryNarrative、星座段落以astroReadings一併回傳;若需要更長的客製解讀,請將結果放入/reading的提問中使用。 - 2026-10-16 變更(
engineVersioncompat-2):新增relations·p2Score·engineVersion,且headerBreakdown.classic改為p2Score,因此headerBreakdown.average可能與以往不同(與 INTA 應用程式合盤畫面相同的值)。其他既有欄位的值不變。 - 相容性:2026-10 新增的欄位(
classic1995·astroSynastry·astroReadings·headerBreakdown·lang,以及 2026-10-10 的saju.relationRatings·saju.meetingKeywords·saju.authority·tti.conflictFrame)無論是否傳送lang都會附加。既有欄位的值不變。但自 2026-10-11 起,轉載參考文獻(1995)文句的欄位 — 生肖合盤一句話解讀,以及日柱辭典中的愛情運、健康運 — 已從回應中移除。 - 2026-10-27 新增:新增
saju.iljuAxes(必定包含,位於saju區塊最後)。既有欄位的值與順序不變,engineVersion也維持compat-2。 - 2026-10-31 變更:修正合盤韓文句子中的助詞,使其符合前一字的收尾音(例:「임와」 → 「임과」、「병는」 → 「병은」)。鍵、順序、數字與其他語言的句子不變。
- 費用:每次呼叫扣除 ₩20(包含新增欄位、
details、flow、MBTI 選項,不另收費)。
錯誤代碼
除了共通錯誤(401、400 內文檢查、402、429、503 等)之外,此 API 會出現的代碼:
| HTTP | 代碼 | 時機 |
|---|---|---|
| 400 | INVALID_BIRTH_YEAR | 兩人中有人的出生年份不在 1900~2100 範圍內 |
| 400 | INVALID_LUNAR_DATE | 不存在的農曆日期 |
| 400 | COMPAT_UNAVAILABLE | 此日柱組合沒有合盤資料 |
| 402 | INSUFFICIENT_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
}
}
價格
- 免費版(free):24 題,₩0(免費)
- 進階版(premium):93 題,₩10/次
- 不存在的
questionId或 1~5 以外的answer會回傳 400,不計費。 - 在
premium中若有完全沒有答案的軸,回傳 400personality_axis_unanswered,不計費。回應的axes會列出空白的軸(E_I·S_N·T_F·J_P)。
錯誤代碼
除了共通錯誤(401、400 內文檢查、402、429、503 等)之外,此 API 會出現的代碼:
| HTTP | 代碼 | 時機 |
|---|---|---|
| 400 | (無) | 題目查詢 — tier 不是 free、premium/提交 — 不存在的 questionId |
| 400 | personality_axis_unanswered | 提交 — premium 但有完全沒有答案的軸(axes 中列出空白的軸) |
| 402 | INSUFFICIENT_BALANCE | 提交 — premium 但餘額不足 |
答案在 1~5 以外時為共通 400。以上皆不計費。
解讀資料庫(KB)API
僅對已申請的帳號開放的 API。未開放的帳號在三個路徑都會收到 404 kb_saju_explain_not_enabled(不計費)。如需使用,請透過支援洽詢。
將八字命盤中成立的關係(合、沖等)與結構(十神、藏干等)以規則卡與解說文字說明。不使用 LLM,相同輸入永遠得到相同結果。
POST /api/v1/partners/v1/kb/saju/explain
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
birth | object | O | 與萬年曆 API 請求內文相同的欄位(year、month、day、hour?、minute?、timezone、gender、calendar? …)。birth.lang 會被忽略。無法辨識 birth.timezone 時,回應會附上 warnings(field: "birth.timezone") |
sections | string[] | relations · structure · all。省略時為全部(依 relations → structure 順序) | |
level | string | L1(預設)· L3。沒有 L3 解說的項目以 L1 補上,並附上 fallbackLevel | |
lang | string | 僅支援 ko | |
channel | string | stable(預設,僅含已審核的解說)· 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": []
}
}
interp是解說欄位(meaning含義、why依據、pitfall注意)。每個欄位為{text, reviewed, reviewedBy?, notes?},在stable中只會出現已審核的欄位。unregistered:已成立但尚無解說的項目。pendingReview:有解說但尚未審核,因此在stable中隱藏的項目。- 規則卡的原典出處可透過下方
GET /kb/rules/{id}查詢。
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 | 代碼 | 時機 |
|---|---|---|
| 404 | kb_saju_explain_not_enabled | 未申請的帳號(三個路徑共通) |
| 400 | INVALID_LUNAR_DATE · INVALID_LOCATION | explain — 不存在的農曆日期/只傳送了緯度、經度其中之一 |
| 403 | KB_PREVIEW_NOT_ALLOWED | explain — 未獲准使用 channel: "preview" 的帳號(不計費) |
| 400 | KB_DOMAIN_UNKNOWN | release — 不支援的 domain |
| 404 | KB_RULE_NOT_FOUND | rules — 不存在的規則 id |
| 503 | KB_NOT_LOADED | 解讀資料庫版本尚未載入。請稍後再試 |
explain 只對成功的呼叫計費,失敗的呼叫記錄為 ₩0。
應用程式郵件寄送 API
讓上架到 RIDM Apps 的應用程式寄送註冊確認、訂單通知、密碼重設等交易、服務通知郵件的 API。只能以應用程式專用金鑰(HRUM_API_KEY,主控台 > 我的應用程式 > AI 連線)呼叫,以一般 API 金鑰呼叫會回傳 403 MAIL_APP_KEY_REQUIRED。應用程式容器封鎖了 SMTP 連接埠,請透過此 API 寄送郵件。
- 寄件地址是 RIDM Apps 的郵件寄件地址,寄件人名稱則是應用程式名稱(可在主控台 > 我的應用程式 > 郵件中修改)後面加上「(RIDM Apps)」(例:
Moonlight Bakery (RIDM Apps))。銀行、信用卡、付款品牌、公家機關(國稅廳、警察、檢察、政府、郵局等),以及 HRUM、RIDM 等名稱不能作為寄件人名稱。回覆會寄到replyTo或主控台中填寫的地址。 - 只有擁有已完成電子郵件驗證之主控台帳號的合作夥伴可以寄送。驗證前會回傳 403
MAIL_EMAIL_UNVERIFIED。 - 不能寄送廣告郵件。主旨以
(광고)(「(廣告)」)開頭時會以 400 拒絕。折扣、活動通知等營利目的的廣告,依韓國《資訊通信網法》第 50 條需要收件人事先同意與拒收方式,因此請勿透過此 API 寄送(條款第 20 條之 2)。 - 每位收件人計為 1 封。一個請求最多可放 10 人,並分別寄給每位收件人,彼此看不到對方的地址。
- 發生退信(不存在的地址)或被檢舉為垃圾郵件的地址,之後不再寄送並回傳
suppressed。這些不計入封數,也不收費。 - 郵件類型(
kind):預設值為transactional(註冊、訂單、密碼等必須寄送的通知),照現在的方式寄送。收件人可以關閉的應用程式通知(新留言、預約提醒等)請以"kind": "notification"寄送。這類郵件會附上一鍵取消訂閱標頭(List-Unsubscribe、List-Unsubscribe-Post,RFC 8058),讓 Gmail 等郵件應用程式可直接按下「取消訂閱」。對已取消訂閱的地址,只會停止寄送該應用程式的notification郵件並回傳suppressed(不計入封數,也不收費)。寄到同一地址的transactional郵件與其他應用程式的郵件照常寄送。notification也不是廣告郵件 — 廣告不論哪種類型都不能寄送。取消訂閱紀錄保存 3 年(1,095 天),之後會刪除,同一地址可能再次收到notification郵件。 - 自動暫停:最近 30 天內垃圾郵件檢舉達寄送封數的 0.1%(至少 2 封)以上,或永久退信達 5%(至少 10 封)以上時(寄送封數少於 200 封則以 200 封計算),會立即停止該應用程式的郵件寄送並通知您。疑似冒名、網路釣魚時亦同。應用程式本身照常運作,暫停期間回傳 403
MAIL_SUSPENDED。如需解除,請寄信至 contact@float.do 申請(條款第 20 條之 2)。
POST /api/v1/partners/v1/mail/send
請求參數
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
to | string | string[] | O | 收件人地址 1~10 個。不接受帶顯示名稱的地址(Name <address>) |
subject | string | O | 主旨 1~200 字,不可換行 |
text | string | △ | 內文(純文字)。text 或 html 至少要有一個。最多 10 萬字 |
html | string | △ | 內文(HTML),最多 20 萬字。寄送前會整理:刪除 script、style、iframe、表單、事件屬性,連結只保留 http(s)、mailto、tel,圖片只保留 https。沒有 text 時,會從 HTML 產生純文字內文一併寄送 |
replyTo | string | 接收回覆的地址。沒有則使用主控台中填寫的地址,若也沒有則不帶回覆地址寄送 | |
attachments | object[] | 附件最多 3 個,合計最多 512KB。{ "filename", "contentType", "content" }(content 為 base64)。只接受 PDF、PNG、JPEG、GIF、WebP、TXT、CSV、ICS | |
kind | string | transactional(預設值)· 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 封 |
錯誤
| HTTP | code | 說明 |
|---|---|---|
| 400 | MAIL_INVALID | 請求有誤。reason 中會說明原因(invalid_recipient、too_many_recipients、subject_invalid、advertising_not_allowed、body_required、attachment_type_not_allowed、attachments_too_large 等) |
| 402 | insufficient_credit | 點數不足以支付額外寄送的費用。不會寄出任何郵件 |
| 403 | MAIL_APP_KEY_REQUIRED | 以非應用程式專用金鑰的金鑰呼叫 |
| 403 | APP_NOT_ACTIVE | 金鑰所連結的應用程式未在運作中 |
| 402 | MAIL_OVERAGE_UNPAID | 未能扣除的額外郵件費用超過餘額。儲值後會扣除未付的費用並重新開放(內含封數內的寄送照常進行) |
| 403 | MAIL_EMAIL_UNVERIFIED | 沒有已完成電子郵件驗證的主控台帳號 |
| 403 | MAIL_SUSPENDED | 超過垃圾郵件檢舉、退信標準,或營運者已暫停,因此此應用程式的郵件寄送已暫停 |
| 429 | MAIL_RATE_LIMITED | 超過每分鐘上限。請在 retryAfterSeconds 後再寄送 |
| 429 | MAIL_DAILY_CAP_EXCEEDED | 超過每日上限。韓國時間午夜重新開放 |
| 429 | MAIL_MONTHLY_LIMIT | 本月內含封數已用完(免費方案,或額外寄送已關閉) |
| 503 | MAIL_UNAVAILABLE | 無法使用郵件伺服器。請稍後再試 |
為網頁元宇宙加上目前線上人數
在 Three.js 等網頁 3D 空間或一般網頁上顯示「目前 N 人在線」的免費功能。在主控台 > 線上人數 註冊網站後,即可取得公開網站金鑰(pk_presence_…)與一行指令碼。不需金鑰、登入,直接在瀏覽器中載入。
- 允許的地址:只計算來自註冊時填寫的地址(https、不含路徑、最多 5 個)的訊號。網站地址的網域也必須在允許的地址中。
- 計算基準:每個分頁每 30 秒傳送一次訊號,最近 75 秒內有訊號的分頁計為「在線」。分頁隱藏時停止傳送訊號,關閉時立即移除。
- 防止灌水:同一分頁的訊號只計算一次(10 秒內的重複會忽略),且同一 IP 增加的分頁數與各網站的訊號數都有上限。空白 User-Agent、自動化工具、無頭瀏覽器的訊號不計算。
放入指令碼
將在主控台 > 線上人數 取得的指令碼放一行到頁面中,並在要顯示數字的位置加上 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 的元素。數字傳回之前為空白。
- 網站金鑰(
pk_presence_…)是公開金鑰,可直接放在頁面原始碼中。即使其他網站拿去使用,只要不是允許的地址就不會計算。 - 分頁不可見時(切到其他分頁或將應用程式移到背景)停止傳送訊號,再次可見時立即傳送一次。關閉或離開分頁時會傳送一次離開訊號,即使此訊號未送達,75 秒後也會移除。
- 在同一分頁重新整理也只算一人。每個分頁會產生隨機的工作階段值,只存放在該分頁的
sessionStorage中。不會傳送 Cookie、登入資訊。 - 金鑰錯誤或網路被封鎖時也不會產生錯誤,只會讓數字保持空白。即使指令碼被放入兩次(標籤管理工具 + 直接放入等),也只會使用先執行的那一個,不會重複計算。
直接使用數字
指令碼會建立 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_…)。伺服器金鑰只在核發時顯示一次,請存放在伺服器的環境變數中,不要放進頁面、瀏覽器程式碼。重新核發後,先前的伺服器金鑰會立即停用。
POST /api/v1/partners/v1/presence/sites/{siteKey}/count· 內文{ "online": integer }(0~100,000)· 標頭X-Presence-Secret: sk_presence_…或Authorization: Bearer sk_presence_…。回應{ online, reportedAt }- 僅限伺服器 → 伺服器,因此不開放瀏覽器 CORS。以公開金鑰(
pk_presence_…)傳送會回傳 401。 - 每個網站每分鐘最多接受一次。更頻繁傳送會回傳 429 與
Retry-After(秒)。 - 最近 5 分鐘內有伺服器傳送的值時,以該值作為線上人數(
source: "server"),超過 5 分鐘則回到指令碼訊號統計(source: "beacon")。也沒有訊號時為 0。 - 值比前一次突然大幅跳升時,仍照樣顯示,但會記錄下來供營運確認。
- 內文只放
online與下方的rooms。有其他欄位時回傳 400。
各房間人數(選用)
若伺服器將房間(頻道、執行個體)分開使用,可在同一個 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" } }
rooms最多 200 個。id為英文、數字、_、-1~64 字(不可使用#、空白),在同一內文中不可重複。n為 0~100,000 的整數,cap為 1~100,000 的整數。房間物件中有其他欄位時回傳 400。n大於cap時回傳 400PRESENCE_ROOM_OVER_CAP。不超過容量收人是房間伺服器的責任,因此超出的值不會儲存。其他格式錯誤會以 400PRESENCE_BAD_REQUEST與field(例:rooms[3].id)告知。回傳 400 時整體數字也不會儲存。- 每次傳送時,房間清單會整個替換。下次回報中沒有的房間會消失,不帶
rooms傳送則視為沒有房間。 - 最後一次回報後 2 分鐘內沒有新回報時,房間清單會讀成空清單(
[])。這與整體數字的 5 分鐘基準是分開的。每分鐘傳送一次就不會中斷。 - 因每分鐘 1 次限制而被擋下的回報(429)也不會變更房間清單。
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"
} }
- 標頭與
count相同(X-Presence-Secret或Authorization: Bearer)。只接受該網站的伺服器金鑰 — 公開金鑰、其他網站的伺服器金鑰、沒有金鑰時回傳 401,已作廢的網站回傳 404。 rooms依id的數字順序(studio-2排在studio-10前面)回傳,free=cap − n。若要從編號小的房間開始填,選擇第一個free > 0的房間即可。reportedAt是最後收到回報的時間(沒有回報過則為null)。即使超過 2 分鐘、房間清單已清空,也可從此值得知最後一次收到的時間。- 僅限伺服器 → 伺服器,因此不開放瀏覽器 CORS,也不快取(
Cache-Control: no-store)。每個網站每分鐘最多 60 次,超過時回傳 429 與Retry-After。 - 只接受房間 id 與人數、容量數字。請勿放入使用者資訊。
伺服器金鑰只放在伺服器上。若將 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 營運的目錄中。網站地址與允許的地址不符時不會顯示。隨時可以關閉。
個人資料
- 不儲存訪客的 IP 位址與 User-Agent。IP 只在記憶體中短暫用於防止濫用的計算,不會記錄。
- 伺服器上只保留
sha256(siteKey + ":" + sid)工作階段雜湊與最後訊號時間,10 分鐘後刪除。不使用 Cookie。 - 「在線」是最近 75 秒內有訊號的分頁數。
錯誤
| HTTP | code | 說明 |
|---|---|---|
| 400 | PRESENCE_BAD_REQUEST · INVALID_BODY | siteKey、sid 格式錯誤,或內文不是 JSON |
| 401 | PRESENCE_SECRET_REQUIRED | 沒有伺服器金鑰或金鑰錯誤(包含以公開金鑰傳送的情況)— 僅限 count |
| 403 | PRESENCE_ORIGIN_NOT_ALLOWED | 沒有 Origin 或不在允許的地址中 |
| 404 | PRESENCE_SITE_NOT_FOUND | 不存在的金鑰或已作廢的金鑰 |
| 413 | PAYLOAD_TOO_LARGE | 內文超過 1KB |
| 429 | PRESENCE_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
- AI 專用的 token(以
hrum_cm_開頭)。以請求標頭Authorization: Bearer hrum_cm_…傳送。 - 預設權限僅限查詢(帳號、金鑰清單、點數、用量、託管、結算狀態)。4 種寫入權限 —
keys(API 金鑰核發、重新核發、作廢)、credit(儲值連結、退款預覽)、hosting(託管申請、解約)、seller(賣家註冊連結)— 由人在核發同意畫面逐一勾選。 hosting_ops(AI 營運 token — 託管中應用程式的環境變數設定、刪除、開始部署、查看部署狀態、復原、重新啟動、查看執行階段日誌)也在核發同意畫面勾選。此權限不會在每次操作時重新取得同意。環境變數、密鑰的設定方式與 AI 路徑允許的名稱,請見RIDM Apps 部署指南 — 以 AI 設定密鑰;開始部署、部署狀態、日誌的查看方式,請見以 AI 部署並查看日誌。- 有效期限為 30 天。每個帳號最多可有 10 個有效 token。
- 可在主控台 API 金鑰 畫面的「AI 主控台管理 token」清單中查看前綴、權限、最後使用時間,並隨時立即撤銷。token 值本身不會再次顯示。
同意流程
- AI 帶著要做的事(做什麼、金額、對象)呼叫
POST /api/v1/partners/v1/console-ai/consents,取得consentUrl與code。 - AI 將連結顯示給使用者(MCP 也可以用瀏覽器開啟)。
- 使用者在已登入主控台的狀態下開啟連結,會看到「AI 提出的請求」標示,以及請求內容原文(金額、對象、名稱)。確認後按下「同意」。付款也是之後在 Toss 付款視窗中由人親自完成。
- 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 · used | read(第一個 token 用 poll secret) | — |
GET /me · GET /token | 我的帳號 · 此 token 的權限 | read | — |
GET /status | 入門檢查清單(API · 託管 · 付款狀態與下一步) | read | — |
GET /keys | API 金鑰清單(僅前綴) | 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?}) | keys | key_issue |
POST /keys/{id}/rotate | 核發新金鑰 + 立即停用此金鑰 | keys | key_rotate |
POST /keys/{id}/revoke | 作廢金鑰(無法復原) | keys | key_revoke |
POST /credit/topup-link | 儲值付款連結({planKey}) | credit | credit_topup_link |
POST /credit/refund-preview | 計算可退款金額(不會提出申請) | credit | credit_refund_preview |
POST /hosting/apply | 申請託管({planKey, subdomain, recurringConsent?}) | hosting | hosting_apply |
POST /hosting/apps/{id}/cancel | 解約託管 | hosting | hosting_cancel |
POST /seller/apply-link | 賣家註冊畫面連結 | seller | seller_apply_link |
寫入請求的內文,是與同意請求 payload 相同的值 + consentCode。新的 API 金鑰只會在該回應中顯示一次。
卡號與賣家本人資料不透過 AI 路徑接收。信用卡付款在 Toss 付款視窗、賣家本人資料、帳戶、條款同意則在主控台畫面中由人親自輸入。payload 中若有規定項目以外的值,會以 400 UNKNOWN_FIELD 拒絕。
錯誤代碼
| 代碼 | HTTP | 含義 |
|---|---|---|
MGMT_TOKEN_INVALID | 401 | 沒有 token,或已過期、撤銷。請重新核發 |
MGMT_SCOPE_DENIED | 403 | 此 token 沒有所需的寫入權限(scope 欄位)。請勾選該權限重新核發 |
ACCOUNT_SUSPENDED | 403 | 已停權的帳號 |
CONSENT_REQUIRED | 400 | 寫入請求中沒有 consentCode |
CONSENT_PENDING | 409 | 尚未由人同意 |
CONSENT_DENIED | 403 | 已由人拒絕 |
CONSENT_EXPIRED | 410 | 超過 10 分鐘,已過期 |
CONSENT_USED | 409 | 已使用過的同意碼 |
CONSENT_MISMATCH | 409 | 同意的內容(金額、對象)與目前的請求不同 |
CONSENT_NOT_FOUND | 404 | 不存在的代碼,或其他帳號的代碼 |
INVALID_CONSENT_PAYLOAD | 400 | payload 值不正確(field 欄位) |
UNKNOWN_FIELD | 400 | 包含不透過 AI 路徑接收的項目 |
CONSENT_RATE_LIMITED | 429 | 同意請求過多 |
MGMT_TOKEN_LIMIT | 409 | 已有 10 個有效 token,無法再核發 |
NOT_AVAILABLE | 404 | 尚未開放的選單 |
以 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 | 代碼 | 時機 |
|---|---|---|
| 429 | GUEST_QUOTA_EXCEEDED | 同一 IP 本月超過 5 次(與本命盤訪客合計) |
| 400 | INVALID_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 術語表。值的種類為上述天干、地支、五行與十神(비견 比肩 · 겁재 劫財 · 식신 食神 · 상관 傷官 · 편재 偏財 · 정재 正財 · 편관 偏官 · 정관 正官 · 편인 偏印 · 정인 正印)。
- 萬年曆 —
wonkuk.*.stem·branch·ohaeng、daeun[]·seun[]的stem·branch·ohaeng、ohaengBalance的鍵、cheonganDetail.seasonal.monthBranch、yongshinDetail.element_states的鍵、byeongyak.primary·tonggwan.primary(五行代碼 — 顯示名稱為primaryLabel)、jeongtak.verdict的 「청」(清)· 「탁」(濁)(只有 「판정불가」(無法判定)會翻譯)、glossary的鍵 - 萬年曆
identity· 八字特質 —saju.{year,month,day,hour}.{cheongan,jiji,ohaeng}、timeline(current · daeunChain · years · highlights)的stem·branch·ohaeng·ganji、gongmang.void_branches[]·gongmang.hits[].jiji、samjae.current_year_branch、season_strength_hint.yongshin_hint.primary[]·secondary[]、sinsal_list[].id(例:sinsal12_재살)、yongshin.element_states的鍵、sipsin_map.* - 萬年曆
astrology: true—natalChart.bodies[].sign、element(英文為signEn)— 與本命盤 API 的寫法相同 - 今日運勢 —
summary.day_master(例:「계」 癸)、summary.ilju(「계미」 癸未)、summary.today_day_ohaeng、summary.yongshin、omen.color.ohaeng - 運勢走勢 — 干支讀音、五行名稱與關係名稱、
chars[].sipsin、natal.level·natal.result(強弱判定,例:「약약」(偏弱)· 「중화」(中和))、natal.primaryYongshin·natal.shin.*、triples[].element、compatInputs.*(包含surfaceElementCounts的鍵) - 合盤 —
saju.personA/B.ilju、dictionary.a/b.id(ilju_경진)、name_kr、yearFlow.years[].a/b的stem、branch、ohaeng、relations[].target、type、saju.full8.personA/B.elementDistribution、sipsinCount、combinedElementBalance.distribution的鍵
直言度(candor)
t、f(預設)— 不區分大小寫。舊值 blunt 會正規化為 t,balanced · gentle 會正規化為 f。其他值回傳 400(直言度(暫定名稱))
錯誤代碼
所有 API 都以相同方式回傳下方的共通錯誤。各 API 章節的錯誤表只列出該 API 專屬的代碼。請求依下列順序檢查,在前面的步驟被擋下時,後面的步驟不會執行。
- 安全規則 — 在抵達 API 伺服器之前過濾被封鎖的 User-Agent(403,內文為 HTML,error 1010)。此時尚未檢查 API 金鑰,因此是 403 而非 401
- 服務保護上限 — 來自同一 IP 的所有請求的每分鐘上限(429,無
code) - API 金鑰 — 確認
X-Partner-Api-Key(401) - 功能是否開放 — 帳號未開放的功能(404
*_not_enabled) - 請求限制 — 在主控台設定的每秒、每日限制(429
RATE_LIMIT_EXCEEDED) - 內文檢查 — 欄位名稱、類型、範圍(400)
- 餘額、計算、呼叫 — 餘額不足(402)、各 API 的輸入錯誤、外部模型錯誤
共通錯誤
| HTTP | 代碼 | 時機 | 計費 |
|---|---|---|---|
| 400 | (無) | 內文檢查失敗 — 傳送了表中沒有的欄位,或類型、範圍錯誤。message 為字串陣列 | 無 |
| 401 | (無) | 缺少 X-Partner-Api-Key、金鑰錯誤、已作廢的金鑰、停用的帳號 | 無 |
| 402 | INSUFFICIENT_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 分鐘後再試 | 無 |
| 429 | RATE_LIMIT_EXCEEDED | 超過在主控台設定的每秒、每日限制。會附上內文 retryAfterSeconds 與 Retry-After 標頭 | 無 |
| 500 | (無) | 伺服器錯誤。此請求中已扣除的金額會在回應後退還 | 退款 |
| 503 | SERVICE_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 為準),即可防止金鑰外洩或無限迴圈耗盡餘額。留空時只套用上述服務保護上限。
- 設定限制後,回應會附上
X-RateLimit-Limit-Second/X-RateLimit-Remaining-Second/X-RateLimit-Limit-Day/X-RateLimit-Remaining-Day標頭。 - 超過合作夥伴設定的限制時,回傳
429+{"code":"RATE_LIMIT_EXCEEDED","retryAfterSeconds":N}以及Retry-After標頭。被擋下的請求不計費。 - 訪客(無金鑰)固定為每月 5 次免費測試。
計費
所有 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(圖片生成 · 模型轉售) | 依模型、解析度、品質每張固定價格 — 價目表 |
訪客測試
- 萬年曆、本命盤訪客端點:合計每月 5 次免費(以 IP 為基礎限制)
- 不需登入即可在 Playground 測試
- 剩餘次數包含在回應中(guestRemaining)
冪等性
每個成功的請求都會個別計費。再次傳送相同請求會重新計算、生成並再次計費,因此重試造成的重複或相同輸入的重複使用,請由用戶端儲存回應來處理(例:以請求雜湊為鍵的快取)。
X-Idempotency-Key 標頭(最多 128 字 — 更長時只記錄前 128 字)仍可傳送,但不會防止計費。傳送的鍵會原樣記錄在用量紀錄的 idempotencyKey 中,可用來將哪個請求以哪次呼叫處理,與合作夥伴端的訂單、工作 ID 對照。
例外:面相、手相解讀在 24 小時內以相同的鍵、相同的內文再次傳送時,會回傳第一次的結果,不會重新計費(重試與重新傳送)。
例外:姓名學在 24 小時內以相同的鍵、相同的內文再次傳送時,會回傳第一次的結果,不會重新計費(重試與重新傳送)。
支援
串接過程中遇到困難,或回應與文件不符時,請告訴我們。
| 洽詢 | 聯絡方式 |
|---|---|
| 技術支援 · 故障回報 · 合作 | contact@float.do |
洽詢時一併提供下列資訊,可加快確認速度。
- 呼叫的端點與時間(含時區)
- API 金鑰前 12 碼(包含
float_live_,絕對不要傳送完整金鑰) - 收到的回應之 HTTP 狀態碼與內文