인증
AstroWay API에 대한 거의 모든 요청은 X-Api-Key 헤더를 통해 인증됩니다. 예외: 14개의 /v1/reference/* 엔드포인트(signs, planets, houses, aspects 등)는 IP당 시간당 30회 요청 제한으로 키 없이 공개적으로 작동합니다. 서버에서 요청하는 경우, X-AstroWay-Site-URL 헤더를 보내면 사이트당 시간당 300회 요청으로 제한이 늘어납니다: 자세히.
모든 계산 엔드포인트 /v1/*(chart, synastry, transits, /reports, /tarot 등)에는 X-Api-Key만 사용됩니다. 사용자 작업 /v1/me/*(GET /me, DELETE /me/account)에는 /v1/auth/login을 통해 발급된 Bearer JWT가 사용됩니다. 공개 API에서는 OAuth/session-cookies가 사용되지 않습니다. **참조 사전 /v1/reference/***는 키 없이 무료로 제공됩니다 (정식 lookup 테이블).
키 형식
섹션 제목: “키 형식”aw_live_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRaw_test_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRaw_live_: 프로덕션, 잔액에서 크레딧이 차감됩니다.aw_test_: 샌드박스, 요청은 스텁 응답(또는 최소한의 실제 계산)을 반환하며, 크레딧이 차감되지 않고, 대시보드에 별도로 표시됩니다.- 접두사 다음: 32자의 base62 문자, 암호학적으로 무작위입니다.
- 키는 생성 시 단 한 번만 일반 텍스트로 표시됩니다. 이후 대시보드에서는 처음 4자와 마지막 4자만 표시됩니다.
요청 헤더
섹션 제목: “요청 헤더”POST /v1/chart HTTP/1.1Host: api.astroway.infoX-Api-Key: aw_live_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRContent-Type: application/jsonPostman 컬렉션
섹션 제목: “Postman 컬렉션”curl/SDK보다 Postman이 더 편리하다면, 모든 771 엔드포인트가 포함된 준비된 컬렉션이 있습니다. 이 컬렉션은 OpenAPI 태그별로 55개의 폴더로 재구성되어 있으며, 예시 요청이 포함되어 있습니다. 인증은 컬렉션 수준에서 설정됩니다: apiKey 변수에 키를 한 번 삽입하면 모든 요청에 적용됩니다.
- 공개 문서: documenter.getpostman.com/view/54689779/2sBXqNmy3n
- 공개 워크스페이스: postman.com/astroway-info/astroway-api
- JSON 다운로드: astroway-api.json (≈ 5 MB) - Postman 또는 Insomnia로 직접 가져오세요.
컬렉션은 OpenAPI spec에서 자동 생성되며, 배포될 때마다 업데이트됩니다.
키 생성 및 관리
섹션 제목: “키 생성 및 관리”대시보드를 통해:
- api.astroway.info/dashboard/keys
- 계정당 최대 10개의 활성 키를 동시에 가질 수 있습니다.
- 각 키에는
name필드(예:production-backend,ci-tests,local-dev)가 있습니다.
API를 통해 (셀프 서비스 통합용):
curl -X POST https://api.astroway.info/v1/keys \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"name": "ci-tests", "mode": "test"}'// Equivalent via @astroway/sdk: aw.client.POST('/keys', { body: { name, mode } })const r = await fetch('https://api.astroway.info/v1/keys', { method: 'POST', headers: { 'X-Api-Key': process.env.ASTROWAY_MASTER_KEY!, 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'ci-tests', mode: 'test' }),});
const { data: created } = await r.json();console.log(created.api_key); // shown once - store it now# Equivalent via `astroway` (PyPI): aw.post('/keys', body={'name': ..., 'mode': ...})import os, requests
r = requests.post( 'https://api.astroway.info/v1/keys', headers={'X-Api-Key': os.environ['ASTROWAY_MASTER_KEY']}, json={'name': 'ci-tests', 'mode': 'test'},)created = r.json()['data']print(created['api_key']) # shown once - store it now<?phpuse GuzzleHttp\Client;
$aw = new Client(['base_uri' => 'https://api.astroway.info/v1/']);$r = $aw->post('keys', [ 'headers' => ['X-Api-Key' => getenv('ASTROWAY_MASTER_KEY')], 'json' => ['name' => 'ci-tests', 'mode' => 'test'],]);
$created = json_decode($r->getBody(), true)['data'];echo $created['api_key']; // shown once - store it now브라우저용 키
섹션 제목: “브라우저용 키”일반적인 키는 서버 전용입니다: 해당 키를 포함한 요청에 Origin 또는 Referer 헤더가 있으면 403 ORIGIN_FORBIDDEN이 반환됩니다. 이는 의도된 것이며, 프론트엔드에 실수로 남겨진 키를 잡아내는 역할을 합니다.
위젯이나 페이지가 브라우저에서 API를 호출해야 하는 경우, 키는 즉시 출처 정책과 함께 생성됩니다. POST /v1/keys의 origin_restriction 필드:
type | 허용되는 것 | 사용 시점 |
|---|---|---|
server-only (기본값) | Origin 및 Referer 없는 요청만 | 백엔드, cron, CI |
public | 나열된 호스트만, 그리고 요청은 출처를 반드시 포함해야 함 | 귀하의 도메인에 있는 위젯 또는 페이지, 소스 코드의 키 |
allowlist | public과 동일 | 더 이상 사용되지 않는 표기법: 계속 허용되지만 openapi.json에는 더 이상 명시되지 않음 |
curl -X POST https://api.astroway.info/v1/keys \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{ "name": "site-widget", "origin_restriction": { "type": "public", "allowed_origins": ["example.com", "*.example.com"] }, "credits_cap_cycle": 20000, "allowed_endpoints": ["chart", "public/*"] }'프로덕션에서 확인된 매칭 규칙:
- 키당 최대 20개의 호스트. 스키마(
https://)와 포트는 무시되며, 대소문자는 중요하지 않습니다. www.는 들어오는 호스트에서 제거되므로,example.com은www.example.com도 포함합니다.www.가 포함된 형태를 별도로 추가할 필요는 없으며, 아무것도 변경하지 않습니다.*.example.com은 서브도메인(app.example.com)을 포함하지만,example.com자체는 포함하지 않습니다. Apex 도메인은 위 예시처럼 별도의 줄로 나열됩니다.- 목록에 없는 호스트는
incoming_origin필드에 해당 호스트와 함께403 ORIGIN_NOT_ALLOWED를 받으므로, 어떤 항목이 누락되었는지 확인할 수 있습니다. Referer는Origin과 동일하게 취급됩니다: 브라우저는Origin이 없는 경우Referer를 보냅니다.
이미 생성된 키의 목록 변경
섹션 제목: “이미 생성된 키의 목록 변경”PATCH /v1/keys/{id}는 키 자체를 건드리지 않고 목록을 덮어씁니다. 접근 권한은 위 POST /v1/keys와 동일하며, 대시보드에서는 키 메뉴의 “출처 변경” 항목입니다.
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{ "origin_restriction": { "type": "public", "allowed_origins": ["example.com", "*.example.com"] } }'새 목록은 다음 요청부터 적용됩니다: 키 캐시는 기록 시 재설정되므로 1분 기다릴 필요가 없습니다. 키 문자열 자체는 변경되지 않으므로, 페이지나 백엔드를 다시 배포할 필요가 없습니다. POST /v1/keys/{id}/rotate 후 목록은 유지되며, 이전 키 값은 즉시 작동을 멈춥니다.
키 클래스는 키 자체에 기록되어 있으므로 편집할 수 없습니다:
| 시도 | 응답 |
|---|---|
pk_를 server-only로 만들기 | 400: 클래스는 키의 일부이므로, 취소하고 새로 생성해야 합니다 |
aw_에 도메인 목록 제공 | 400: 브라우저 키는 다른 클래스이며, public으로 생성됩니다 |
pk_에 빈 목록 제공 | 400: 목록이 없는 키는 모든 요청을 거부할 것입니다 |
pk_에 예산 또는 범위 없음 (null) | 400: 브라우저용 키는 항상 둘 다로 제한되며, 변경할 수는 있지만 제거할 수는 없습니다 |
개별 키에 대한 크레딧 예산
섹션 제목: “개별 키에 대한 크레딧 예산”크레딧은 전체 계정에서 공유되므로, 하나의 키가 모든 크레딧을 소진할 수 있습니다. 백엔드 키에는 정상적이지만, 페이지 소스 코드의 키에는 그렇지 않습니다: 도메인 목록은 어디에서 접근할 수 있는지 알려주지만, 비용이 얼마나 들지는 알려주지 않습니다.
동일한 PATCH /v1/keys/{id}의 credits_cap_cycle은 이 키를 제한합니다:
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"credits_cap_cycle": 5000}'null은 제한을 제거합니다 (pk_ 키 제외, 이 키는 예산을 변경할 수 있지만 제거할 수는 없습니다). 0은 아무것도 사용할 수 없는 키를 의미합니다: 키를 취소하지 않고 보관하는 방법입니다. 카운터는 크레딧과 동일하며, 요금제 주기와 함께 재설정됩니다.
키가 예산에 도달하면, 계정에 크레딧이 남아 있거나 초과 요금제인 경우에도 429 KEY_BUDGET_EXHAUSTED가 반환됩니다: 돈을 지불하고 초과 사용할 수 있는 예산은 예산이 아닙니다. 예산이 설정되어 있는 동안, 모든 응답에는 X-Key-Budget-Limit 및 X-Key-Budget-Remaining이 포함됩니다.
엔드포인트 범위
섹션 제목: “엔드포인트 범위”범위가 없는 키는 요금제에 포함된 모든 것을 호출합니다. allowed_endpoints는 이를 경로 목록으로 좁힙니다: 정확한 경로(chart) 또는 네임스페이스(embed/*). 이는 세 번째 독립적인 제한입니다: 도메인 목록은 어디에서, 예산은 얼마만큼, 범위는 무엇을 호출할지 지정합니다.
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"allowed_endpoints": ["embed/*", "public/moon-phase"]}'null은 제한을 제거합니다 (pk_ 키 제외, 이 키는 범위가 필수입니다). 빈 목록은 허용되지 않습니다: “모든 것” 또는 “아무것도 아님”으로 동일하게 해석될 수 있기 때문입니다. 경로는 /v1에 상대적으로 작성되며, 선행 슬래시 없이 대소문자는 중요하지 않습니다.
목록 외 호출은 403 ENDPOINT_NOT_IN_SCOPE를 받으며, details는 목록 자체를 명시하여 추측할 필요가 없도록 합니다. 범위는 두 가지 키 클래스와 /v1/public/* 및 /v1/embed/*에 대해서도 다른 엔드포인트와 동일하게 적용됩니다. 크레딧과 달리 서비스 읽기는 면제되지 않습니다: embed/*로 제한된 키는 자체 통계도 읽을 수 없습니다. 이는 의도된 것입니다. 페이지 소스 코드의 키는 방문자에게 계정 비용을 노출해서는 안 되며, 키 관리를 방해하지 않습니다: 대시보드는 키가 아닌 세션으로 작동합니다.
모범 사례
섹션 제목: “모범 사례”1. 서버 전용 키를 프론트엔드에 두지 마세요.
섹션 제목: “1. 서버 전용 키를 프론트엔드에 두지 마세요.”일반적인 키는 백엔드 수준의 비밀입니다. 사용자 브라우저에서 실행되는 JS에 포함되면 DevTools에서 볼 수 있으며 유출될 것입니다. 이것이 바로 이러한 키가 Origin 또는 Referer가 포함된 모든 요청에 403 ORIGIN_FORBIDDEN으로 응답하는 이유입니다.
브라우저에서 접근해야 하는 경우, 일반 키가 아닌 origin_restriction.type: "public"으로 생성된 별도의 키를 사용합니다: 브라우저용 키. 이러한 키는 pk_ 접두사를 가지며, DevTools에서도 볼 수 있습니다. 이것이 핵심입니다. 이 키의 가치는 귀하의 도메인 목록으로 제한되며, 출처 없는 요청은 거부합니다.
올바른 방법: 귀하의 백엔드가 키를 보유하고, 프론트엔드는 귀하의 백엔드를 호출하며, 귀하의 백엔드는 AstroWay API를 호출합니다.
잘못된 방법:
// DO NOT DO THISfetch('https://api.astroway.info/v1/chart', { headers: { 'X-Api-Key': 'aw_live_...' }, // visible in browser});2. 환경 변수 사용, 하드코딩 금지
섹션 제목: “2. 환경 변수 사용, 하드코딩 금지”# .env (in .gitignore)ASTROWAY_API_KEY=aw_live_...// in codeconst key = process.env.ASTROWAY_API_KEY;if (!key) throw new Error('ASTROWAY_API_KEY is not set');3. 환경별 개별 키 사용
섹션 제목: “3. 환경별 개별 키 사용”production-backend: 프로덕션staging-backend: 스테이징ci-tests: CI/CD 파이프라인local-dev-maksym: 각 개발자의 로컬 개발
하나의 키가 손상되면 해당 키만 취소하고, 다른 키는 계속 작동합니다.
4. 로테이션
섹션 제목: “4. 로테이션”권장 주기는 90일마다 한 번입니다. 또는 유출 의심이 있는 경우 즉시 로테이션하세요.
다운타임 없는 로테이션:
- 동일한
name+-v2로 새 키를 생성하세요. - 프로덕션에 배포하세요 (이전 키와 병렬로).
- 사용량이 새 키로 흐르는지 확인하세요 (대시보드).
- 이전 키를 취소하세요.
5. 사용량 모니터링
섹션 제목: “5. 사용량 모니터링”대시보드는 키별로 요청을 개별적으로 보여줍니다. 갑자기 하나의 키가 평소보다 10배 더 많은 요청을 시작했다면, 이는 확인해야 할 신호입니다.
알림을 설정할 수 있습니다: Settings → Notifications → Alert when daily credits > X.
인증 오류
섹션 제목: “인증 오류”| 코드 | 의미 |
|---|---|
401 Unauthorized | X-Api-Key 헤더가 없거나 키가 유효하지 않습니다 |
403 Forbidden | 키는 유효하지만 이 작업에 대한 scope가 없습니다 (예: 일반 키가 다른 키를 관리하려고 시도) |
403 PUBLISHABLE_KEY_UNBOUNDED | credits_cap_cycle 예산 또는 allowed_endpoints 범위가 없는 pk_ 키: 키 설정에서 둘 다 지정하세요 |
402 Payment Required | 크레딧이 소진되었거나 (무료 요금제에서) 구독이 비활성 상태입니다 |
429 Too Many Requests | 요금제에 따라 rate limit이 초과되었습니다 (10/60/300 req/min) |
401 예시:
{ "error": { "code": "invalid_api_key", "message": "The API key provided is invalid or has been revoked.", "request_id": "8aec43e9bc749b37e998a489bbad1757" }}샌드박스 모드
섹션 제목: “샌드박스 모드”aw_test_ 접두사가 붙은 키는 샌드박스에서 작동합니다:
- 크레딧이 차감되지 않습니다.
- 스텁 또는 최소한의 실제 응답을 반환합니다.
- 프로덕션 통계에 영향을 미치지 않습니다.
- 사용 가능한 엔드포인트: 동일합니다.
CI/CD, e2e 테스트 및 로컬 개발에 유용합니다. 대시보드에서 한 번의 클릭으로 생성됩니다.