API 문서
사주 API
생년월일을 보내면 명리 판정을 계산해 돌려줍니다. 엔드포인트는 질문 단위로 12종이고,
응답에는 판정 근거 문장과 용어집이 함께 실립니다. 모든 경로는 https://api.supasaju.com 아래입니다.
인증
x-api-key 헤더에 키를 담습니다. Authorization: Bearer 도 받습니다.
curl https://api.supasaju.com/v2/me -H "x-api-key: $SAJU_API_KEY"
키는 대시보드에서 발급합니다. 발급 직후 한 번만 보여 주고 저장하지 않으므로, 그 자리에서 안전한 곳에 옮겨 두십시오. 키는 브라우저에 두지 마십시오 — 서버에서만 부르십시오.
5분 시작하기
1. 키를 발급합니다. 2. 아래를 그대로 실행합니다. 3. 받은 JSON 을 LLM 에 넘깁니다.
curl -X POST https://api.supasaju.com/v2/saju/manse \
-H "x-api-key: $SAJU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"birthYear": 1988,
"birthMonth": 3,
"birthDay": 14,
"birthHour": 9,
"birthMinute": 20,
"isFemale": false,
"isLunar": false,
"birthCity": "서울"
}'const res = await fetch('https://api.supasaju.com/v2/saju/manse', {
method: 'POST',
headers: {
'x-api-key': process.env.SAJU_API_KEY!,
'content-type': 'application/json',
},
body: JSON.stringify({
"birthYear": 1988,
"birthMonth": 3,
"birthDay": 14,
"birthHour": 9,
"birthMinute": 20,
"isFemale": false,
"isLunar": false,
"birthCity": "서울"
}),
})
const { data } = await res.json()
// 판정 근거 문장만 모읍니다 — 이게 풀이의 재료입니다.
const facts: string[] = []
const walk = (v: unknown, path = ''): void => {
if (Array.isArray(v)) return v.forEach((x, i) => walk(x, `${path}[${i}]`))
if (v === null || typeof v !== 'object') return
for (const [k, x] of Object.entries(v)) {
if (typeof x === 'string' && ['reasoning', 'basis', 'meaning'].includes(k)) facts.push(x)
else walk(x, path ? `${path}.${k}` : k)
}
}
walk(data.modules)
// guide 와 glossary 를 함께 실어 넘깁니다.
const prompt = [
data.guide.purpose,
...data.guide.howToUse,
'',
'용어의 뜻:',
...Object.entries(data.glossary).map(([t, d]) => `- ${t}: ${d}`),
'',
'계산된 사실:',
...facts.map((f) => `- ${f}`),
'',
'위 사실만으로 존댓말 6문장으로 풀어 주세요.',
].join('\n')import os, json, requests
res = requests.post(
"https://api.supasaju.com/v2/saju/manse",
headers={"x-api-key": os.environ["SAJU_API_KEY"]},
json={
"birthYear": 1988,
"birthMonth": 3,
"birthDay": 14,
"birthHour": 9,
"birthMinute": 20,
"isFemale": False,
"isLunar": False,
"birthCity": "서울"
},
)
data = res.json()["data"]
# 판정 근거 문장만 모읍니다 — 이게 풀이의 재료입니다.
FACT_KEYS = {"reasoning", "basis", "meaning"}
facts = []
def walk(v):
if isinstance(v, list):
for x in v:
walk(x)
elif isinstance(v, dict):
for k, x in v.items():
if isinstance(x, str) and k in FACT_KEYS:
facts.append(x)
else:
walk(x)
walk(data["modules"])
# guide 와 glossary 를 함께 실어 넘깁니다.
prompt = "\n".join([
data["guide"]["purpose"],
*data["guide"]["howToUse"],
"",
"용어의 뜻:",
*[f"- {t}: {d}" for t, d in data["glossary"].items()],
"",
"계산된 사실:",
*[f"- {f}" for f in facts],
"",
"위 사실만으로 존댓말 6문장으로 풀어 주세요.",
])공통 요청 필드
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
birthYear | number | 필수 | 1900~2100 |
birthMonth | number | 필수 | 1~12. JavaScript Date.getMonth() 의 0~11 을 그대로 보내면 어긋납니다. |
birthDay | number | 필수 | 1~31 |
birthHour | number | null | 선택 | 0~23. 모르면 null — 시주 없이 계산합니다 |
birthMinute | number | 선택 | 0~59. 기본 0 |
isFemale | boolean | 선택 | 기본 false. 대운 순역이 갈리므로 가능하면 보내십시오 |
isLunar | boolean | 선택 | 음력 입력 여부. 기본 false |
isLeapMonth | boolean | 선택 | 음력 윤달. 빠뜨리면 한 달이 어긋납니다 |
birthCity | string | 선택 | 진태양시 보정 기준. 기본 서울. 목록은 birth-cities.json |
timeMode | 'trueSolar' | 'convention' | 선택 | 진태양시 / 표준시 관행. 기본 진태양시 |
date · month · year | string | number | 토픽별 | 기준 시점. 토픽마다 하나만 쓰입니다 |
partners | object[] | 토픽별 | 상대 최대 3인. 궁합·연애에서 씁니다 |
decadeWindow | number | 선택 | 현재 대운 ±n (0~9). 응답을 크게 줄입니다 — 응답 크기 |
seunWindow | number | 선택 | 기준 연도 ±n 개의 세운 (0~5). 연간 운세·고민 상담은 기본 1(3개년) |
decadeCount | number | 선택 | 첫 대운부터 n개 (1~20, 기본 13) |
detail | 'minimal' | 'standard' | 'full' | 선택 | 해설 분량. 기본 standard |
문자열로 된 정수("1988")도 받습니다. 강제 변환이 일어나면
meta.warnings 와 X-Input-Coerced 헤더로 알려 드립니다 — 조용히 고치지 않습니다.
응답 구조
{
"success": true,
"data": {
"topic": "manse",
"guide": {
"purpose": "…",
"howToUse": [
"…"
]
},
"glossary": {
"원국": {
"definition": "…",
"en": "Natal Chart"
}
},
"reference": null,
"input": {
"…": "정규화된 입력"
},
"timezone": {
"…": "적용된 시각 보정"
},
"modules": {
"fourPillars": "…"
},
"diagnostics": [],
"ruleset": {
"version": "0.2.1",
"profile": "ko-standard"
}
},
"meta": {
"topic": "manse",
"modules": [
"…"
],
"tier": "pro",
"responseMs": 8,
"cached": false
}
}
| 키 | 무엇인가 |
|---|---|
data.guide | 이 응답을 어떻게 쓰는지. 그대로 프롬프트에 넣으십시오 — 지어내지 말라는 지시가 들어 있습니다 |
data.glossary | 이 응답에 나온 용어의 definition(한국어 뜻)과 en(영문 용어명). LLM 이 용어를 제멋대로 정의하거나 옮기는 것을 막습니다 |
data.input | 정규화된 입력. 기본값이 적용된 결과를 되돌려 줍니다 |
data.timezone | 진태양시 보정 내역. 표준시와 몇 분 차이인지 담깁니다 |
data.modules | 본체. 계산된 판정과 그 근거 문장 |
data.diagnostics | 계산 중 알려 둘 것. 비어 있으면 특이사항 없음 |
data.ruleset | 판정 규칙 버전. 규칙이 바뀌면 같은 입력의 결과가 바뀔 수 있습니다 |
meta.gatedModules | 플랜 때문에 빠진 모듈. 상향하면 받습니다 |
meta.pendingModules | 아직 제공되지 않는 모듈. 플랜과 무관합니다 |
응답 크기와 LLM 비용
응답을 통째로 LLM 에 넣기 전에 이 절을 읽어 주십시오. 저희 응답은 큽니다. 판정마다 근거 문장을 달고 간지마다 파생 표기를 함께 실어서 그렇습니다. 그게 이 API 의 값어치지만, 그대로 프롬프트에 넣으면 LLM 입력 비용이 저희 호출 요금보다 큽니다.
| 토픽 | 응답 | 대략 토큰 | 해설 문장 |
|---|---|---|---|
| 만세력 | 54KB | 25,343 | 62 |
| 오늘의 운세 | 45KB | 20,719 | 72 |
| 일일 운세 | 69KB | 32,324 | 86 |
| 월 운세 | 48KB | 22,498 | 76 |
| 연간 운세 | 78KB | 36,253 | 113 |
| 대운 10년 | 63KB | 29,287 | 71 |
| 평생 흐름 | 65KB | 30,427 | 94 |
| 고민 상담 | 78KB | 36,210 | 119 |
| 관계 궁합 | 68KB | 31,596 | 104 |
| 연애 운 | 85KB | 39,552 | 135 |
| 금전운 | 72KB | 33,411 | 76 |
| 건강운 | 43KB | 20,215 | 74 |
샘플 프로필 기준입니다. 토큰 수는 한글 기준 어림이며 모델마다 다릅니다.
줄이는 방법
1. 필요한 문장만 뽑으십시오. 응답의 3분의 1이 문장이고 나머지는 구조와 파생 표기입니다.
LLM 에게는 문장만 있으면 됩니다. 각 토픽 페이지의 LLM 연동 예시가 그렇게 합니다 —
reasoning·basis·meaning 만 걷어 내면 원본의 3분의 1 이하로 줄어듭니다.
2. detail 을 쓰십시오. minimal 은 판정값만 돌려주고 해설을 뺍니다.
문장을 직접 쓰실 거라면 이쪽이 맞습니다. 반대로 근거 문장이 필요하시면
minimal 을 쓰지 마십시오 — reasoning·basis 가
정확히 그것이 지우는 것입니다. 그때는 아래 4·6 번으로 줄이십시오.
full 이 standard 에 더하는 것은
대운 항목의 원국 관계·12신살·공망, 그리고 운 12신살·운 신살의 뜻풀이입니다.
사주 고유의 판정 문장은 이미 standard 에 있습니다. 그래서
오늘의 운세·월 운세·건강운에서는 full 이 standard 와 거의 같습니다
(2~5%) — 대운이 구성에 없거나 비중이 작은 토픽이라 더할 것이 남지 않습니다.
이 세 토픽에서는 full 을 부를 이유가 없습니다.
3. 필요한 토픽만 부르십시오. 토픽마다 모듈 구성이 다릅니다. “연애 운”은 모듈 10종이라 가장 무겁고, “건강운”·“오늘의 운세”는 그 절반입니다.
4. 안 쓰는 모듈을 빼십시오 — exclude.
덩치는 문장이 아니라 구조입니다. 그래서 detail 을 내리는 것보다
모듈 하나를 빼는 편이 대개 더 크게 줄어듭니다. 실측입니다.
| 토픽 | 기본 | 가장 큰 모듈 하나를 빼면 | 줄어드는 폭 |
|---|---|---|---|
| 연간 운세 | 78KB | exclude: ["decadeFortune"] | −32% |
| 평생 흐름 | 65KB | exclude: ["decadeFortune"] | −39% |
| 고민 상담 | 78KB | exclude: ["decadeFortune"] | −32% |
토픽의 핵심 모듈은 뺄 수 없습니다 — 빼고 나면 그 토픽이 답하기로 한
질문에 아무 말도 못 하는 응답이 되므로 400 으로 거절하고 어느 모듈인지 알려 드립니다.
모듈 이름은 GET /v2/saju/modules 에 있고, 무엇을 뺐는지는 응답의
meta.excluded 에 담겨 옵니다. 그 토픽에 원래 없는 모듈을 적어도 탈나지 않습니다.
5. 얼마나 되는지는 응답이 알려 줍니다.
모든 응답의 meta.approxTokens 에 이 응답이 LLM 컨텍스트에서 차지할
대략의 토큰 수가 담깁니다. 어림이며 모델마다 다릅니다 — 예산을 재는 용도입니다.
6. 대운을 필요한 만큼만 받으십시오. 대운 한 개가 약 3KB라 가장 큰 지렛대입니다.
두 가지 방법이 있고, 대개는 decadeWindow 쪽이 맞습니다.
| 파라미터 | 뜻 | 언제 쓰나 |
|---|---|---|
decadeWindow0~9 | 현재 대운을 가운데 두고 앞뒤 n개. 1 이면 3개(이전·현재·다음) | 보통 이쪽입니다. 크기를 줄이면서도 현재 대운을 잃지 않습니다 |
decadeCount1~20, 기본 13 | 첫 대운부터 n개 | 평생 흐름처럼 전 생애를 훑을 때. 작게 주면 현재 대운이 목록 밖으로 나갑니다 |
둘을 함께 보내면 decadeWindow 가 이깁니다.
decadeCount: 3 은 서른여덟 살에게 7·17·27세 대운을 줍니다 — 그때
decadeFortune.current.phase 가 "after" 로 오고 사유가 문장으로 담기므로
조용히 틀리지는 않지만, 원하던 답도 아닐 것입니다.
어느 쪽으로 골랐는지는 decadeFortune.selection 에 담겨 옵니다.
판정을 LLM 에게 다시 시키지 마십시오. 문장만 넘기고 요약과 톤 변환만 맡기면, 토큰도 줄고 결과도 정확해집니다. 원본 JSON 을 통째로 넣는다고 풀이가 좋아지지 않습니다 — 오히려 LLM 이 숫자를 제멋대로 해석합니다.
Free 샌드박스
Free 키는 기초 모듈 3종(fourPillars · elements · decadeFortune)을
임의의 생년월일로 계산합니다. 나머지 모듈은 샘플 프로필 입력일 때만 유료와 같은 구성으로 응답합니다.
핵심 모듈이 무료 범위인 토픽은 임의의 생년월일로도 온전히 쓸 수 있습니다 — 만세력 · 대운 10년 · 관계 궁합.
| 프로필 | 무엇을 보는 케이스인가 |
|---|---|
male-forward남 · 대운 순행 | 기본 형태. 네 기둥이 모두 차고 대운이 순행하는 표준 케이스 |
female-reverse여 · 대운 역행 | 대운이 역순일 때의 정렬·나이 표기. 순행만 가정한 화면이 깨지는 자리 |
unknown-hour출생시간 미상 | 시주가 null 인 응답. 기둥 하나가 비는 화면과 null 처리 |
lunar-leap음력 윤달 출생 | 음력·윤달 입력의 양력 환산. isLeapMonth 를 빠뜨리면 한 달이 어긋난다 |
overseas해외 출생 (뉴욕) | 현지 표준시·서머타임·경도 보정. 한국 기준만 가정한 구현이 틀리는 자리 |
GET /v2/saju/samples 로 입력값을 그대로 받아 쓸 수 있습니다.
요청 한도
한도는 차단입니다. 넘으면 막힐 뿐 초과 요금이 붙지 않습니다.
| 무엇 | 어떻게 |
|---|---|
| 분당 | 고정 창으로 셉니다. Free 는 분당 1회 |
| 월 | 포함량을 다 쓰면 402 QUOTA_EXCEEDED |
| 하루 | 월 포함량의 일정 비율까지. 재시도 루프가 월 한도를 태우는 것을 막습니다 |
| 카탈로그·샘플·키 상태 조회 | 분당 한도에 세지 않습니다. 유틸리티가 한 칸을 먹으면 첫 리딩이 바로 막히기 때문입니다 |
응답 헤더
| 헤더 | 뜻 |
|---|---|
X-RateLimit-Limit · -Remaining · -Reset | 분당 한도와 잔여, 창이 열리는 시각 |
X-Quota-Limit · -Used | 월 포함량과 사용량 |
X-Daily-Limit · -Used | 하루 상한과 사용량. 상한이 꺼져 있으면 오지 않습니다 |
X-Input-Coerced | 입력을 강제 변환했을 때, 어떤 필드였는지 |
CORS
키를 브라우저에 두지 마십시오. 이 API 는 서버에서 부르는 것을 전제합니다. 대시보드에서 도메인을 등록하면 그 출처에 한해 브라우저 호출을 허용하지만, 키 노출 위험은 그대로 남습니다.