> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sajuapi.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 인증

> API 키로 요청 보안 설정하기

## API 키

모든 API 요청은 `X-API-Key` 헤더를 통한 API 키 인증이 필요합니다.

```bash theme={null}
curl -X POST https://api.sajuapi.dev/api/daily-fortune \
  -H "X-API-Key: bs_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{...}'
```

## 키 종류

| 종류   | 접두사        | 환경   | 요청 제한      |
| ---- | ---------- | ---- | ---------- |
| Live | `bs_live_` | 프로덕션 | 1,000 요청/분 |
| Test | `bs_test_` | 개발   | 100 요청/분   |

<Warning>
  테스트 키는 목업 데이터를 반환하며 비용이 청구되지 않습니다. 개발 중에 사용하세요.
</Warning>

## API 키 발급받기

### 대시보드에서 발급

1. [dashboard.sajuapi.dev](https://dashboard.sajuapi.dev)에 로그인
2. **설정** → **API 키**로 이동
3. **새 키 생성** 클릭
4. 키를 즉시 복사 (다시 표시되지 않음)

### API로 발급 (프로그래밍 방식)

```bash theme={null}
curl -X POST https://api.sajuapi.dev/api/keys \
  -H "Authorization: Bearer your_access_token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "프로덕션 키",
    "type": "live",
    "permissions": ["fortune:read", "saju:calculate"]
  }'
```

## 키 권한

| 권한               | 설명             |
| ---------------- | -------------- |
| `fortune:read`   | 일일 운세 엔드포인트 접근 |
| `saju:calculate` | 사주 계산          |
| `stream:read`    | 스트리밍 엔드포인트 접근  |
| `usage:read`     | 사용량 통계 조회      |

## 보안 모범 사례

<AccordionGroup>
  <Accordion title="클라이언트 코드에 키를 노출하지 마세요">
    API 키는 서버 측에서만 사용해야 합니다. 클라이언트 애플리케이션의 경우, 백엔드에 프록시 엔드포인트를 생성하세요.

    ```javascript theme={null}
    // ❌ 잘못된 예: 브라우저에 노출됨
    fetch('https://api.sajuapi.dev/api/daily-fortune', {
      headers: { 'X-API-Key': 'bs_live_xxx' }  // DevTools에서 보임!
    });

    // ✅ 올바른 예: 백엔드를 통해 프록시
    fetch('/api/fortune', { method: 'POST' });
    ```
  </Accordion>

  <Accordion title="정기적으로 키를 교체하세요">
    프로덕션 키를 90일마다 교체하세요. 다운타임 없는 교체를 위해 최대 3개의 활성 키를 동시에 가질 수 있습니다.
  </Accordion>

  <Accordion title="환경 변수를 사용하세요">
    키를 코드가 아닌 환경 변수에 저장하세요.

    ```bash theme={null}
    # .env
    SAJU_API_KEY=bs_live_xxxxxxxxxxxxxxxxxxxxxxxx
    ```

    ```javascript theme={null}
    const apiKey = process.env.SAJU_API_KEY;
    ```
  </Accordion>

  <Accordion title="키 권한을 최소화하세요">
    서비스별로 최소한의 필요 권한만 가진 별도의 키를 생성하세요.
  </Accordion>
</AccordionGroup>

## 에러 응답

| 상태 코드 | 에러                         | 설명                    |
| ----- | -------------------------- | --------------------- |
| 401   | `missing_api_key`          | API 키가 제공되지 않음        |
| 401   | `invalid_api_key`          | API 키가 잘못되었거나 존재하지 않음 |
| 401   | `expired_api_key`          | API 키가 폐기되었거나 만료됨     |
| 403   | `insufficient_permissions` | 키에 필요한 권한이 없음         |

```json theme={null}
{
  "success": false,
  "error": {
    "code": "invalid_api_key",
    "message": "제공된 API 키가 유효하지 않습니다",
    "hint": "키가 'bs_live_' 또는 'bs_test_'로 시작하는지 확인하세요"
  }
}
```

## SDK 인증

<CodeGroup>
  ```javascript JavaScript SDK theme={null}
  import { SajuClient } from '@sajuapi/sdk';

  const client = new SajuClient({
    apiKey: process.env.SAJU_API_KEY
  });

  const fortune = await client.getDailyFortune({
    saju: {...},
    userName: '홍길동'
  });
  ```

  ```python Python SDK theme={null}
  from sajuapi import SajuClient

  client = SajuClient(api_key=os.environ['SAJU_API_KEY'])

  fortune = client.get_daily_fortune(
      saju={...},
      user_name='홍길동'
  )
  ```
</CodeGroup>
