External Health API 엔드포인트
목차
- 관련 문서
- 접근 권한 매트릭스
- 데이터 수집 요청 API
- 데이터 수집 응답 API
- 건강 데이터 조회 API
- 플랫폼 연동 API
- 외부 수면 데이터 API
- 데이터 관리 API
- 오류 코드
- 변경 이력
관련 문서
- Sleep 도메인 엔드포인트: /domains/common/core-domains/sleep/endpoints
- Agent Data 도메인 엔드포인트: /domains/common/core-domains/agent-data/endpoints
접근 권한 매트릭스
| 엔드포인트 | System Admin | IAM Admin | Service Account | Regular User | 비고 |
|---|---|---|---|---|---|
| POST /v1/external-health/requests | ✓ | ✓ | ✓ | ✘ | LLM/Agent용 요청 생성 |
| POST /v1/external-health/requests/batch | ✓ | ✓ | ✓ | ✘ | 일괄 요청 생성 |
| GET /v1/external-health/requests | ✓ | ✓ | ✓ | ✓ | 대기 중인 요청 조회 |
GET /v1/external-health/requests/{requestId} | ✓ | ✓ | ✓ | ✓ | 특정 요청 상세 조회 |
PATCH /v1/external-health/requests/{requestId}/cancel | ✓ | ✓ | ✓ | ✘ | 요청 취소 |
| POST /v1/external-health/responses | ✓ | ✓ | ✓ | ✓ | 수집 데이터 제출 |
| GET /v1/external-health/data | ✓ | ✓ | ✓ | ✓ | 건강 데이터 조회 |
| GET /v1/external-health/data/day-index-range | ✓ | ✓ | ✓ | ✓ | 일차 범위별 조회 |
| GET /v1/external-health/data/summary | ✓ | ✓ | ✓ | ✓ | 데이터 요약 조회 |
| GET /v1/external-health/platforms | ✓ | ✓ | ✓ | ✓ | 플랫폼 연동 목록 조회 |
| POST /v1/external-health/platforms/connect | ✓ | ✓ | ✓ | ✓ | 플랫폼 연동 |
| POST /v1/external-health/platforms/disconnect | ✓ | ✓ | ✓ | ✓ | 플랫폼 연동 해제 |
| PATCH /v1/external-health/platforms/permissions | ✓ | ✓ | ✓ | ✓ | 권한 업데이트 |
| GET /v1/external-health/sleep-data | ✓ | ✓ | ✓ | ✓ | 외부 수면 데이터 조회 |
GET /v1/external-health/admin/users/{userId}/data | ✓ | ✓ | ✓ | ✘ | 관리자 데이터 접근 |
DELETE /v1/external-health/admin/users/{userId}/data | ✓ | ✓ | ✘ | ✘ | 사용자 데이터 삭제 |
| GET /v1/external-health/users/me/data-export | ✘ | ✘ | ✘ | ✓ | 내 데이터 내보내기 |
GET /v1/external-health/admin/users/{userId}/data-export | ✓ | ✓ | ✘ | ✘ | 특정 사용자 데이터 내보내기 |
참고:
- ✓: 접근 가능
- ✘: 접근 불가
- Service Account: Multi-Agent Orchestration 도메인의 LLM/Agent가 사용
데이터 수집 요청 API
데이터 수집 요청 API는 LLM/Agent가 개인화된 건강 데이터 수집 요청을 생성하고, 앱에서 대기 중인 요청을 조회하는 기능을 제공합니다.
1.1 데이터 수집 요청 생성 API
- HTTP 메서드: POST
- 경로: /v1/external-health/requests
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{serviceAccountToken}
요청 (Request)
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"type": "heartRate",
"startTime": 1702684800000,
"endTime": 1702771200000,
"interval": {
"type": "hour",
"value": 1
},
"requestedBy": "agent_sleep_analyst",
"context": {
"analysisType": "sleep_quality_prediction",
"priority": "NORMAL",
"reason": "심박수 변화 패턴 분석을 위한 데이터 수집"
},
"expiresInHours": 24
}
참고:
type: 수집할 데이터 유형 (stepCount, heartRate, heartRateVariability, respiratoryRate, oxygenSaturation, activeEnergyBurned, sleepAnalysis)startTime,endTime: Unix 타임스탬프 (밀리초)interval: 집계 간격 설정requestedBy: 요청자 식별자 (agent_id, system 등)expiresInHours: 만료 시간 (선택, 기본 24시간, 범위 1-168시간)
응답 (Response)
- 성공 응답 (201 Created)
{
"id": "req_550e8400-e29b-41d4-a716-446655440001",
"userId": "550e8400-e29b-41d4-a716-446655440000",
"dayIndex": 15,
"type": "heartRate",
"startTime": 1702684800000,
"endTime": 1702771200000,
"interval": {
"type": "hour",
"value": 1
},
"status": "PENDING",
"expiresAt": 1702857600000,
"requestedBy": "agent_sleep_analyst",
"context": {
"analysisType": "sleep_quality_prediction",
"priority": "NORMAL",
"reason": "심박수 변화 패턴 분석을 위한 데이터 수집"
},
"timezoneId": "Europe/Berlin",
"timezoneOffset": 60,
"createdAt": 1702771200000,
"updatedAt": 1702771200000
}
- 오류 응답 (400 Bad Request)
{
"code": 21001,
"message": "INVALID_DATA_TYPE",
"detail": "지원하지 않는 데이터 유형입니다."
}
1.2 데이터 수집 요청 일괄 생성 API
- HTTP 메서드: POST
- 경로: /v1/external-health/requests/batch
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{serviceAccountToken}
요청 (Request)
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"requests": [
{
"type": "heartRate",
"startTime": 1702684800000,
"endTime": 1702771200000,
"interval": { "type": "hour", "value": 1 }
},
{
"type": "stepCount",
"startTime": 1702684800000,
"endTime": 1702771200000,
"interval": { "type": "day", "value": 1 }
},
{
"type": "sleepAnalysis",
"startTime": 1702684800000,
"endTime": 1702771200000,
"interval": { "type": "day", "value": 1 }
}
],
"requestedBy": "agent_sleep_analyst"
}
응답 (Response)
- 성공 응답 (201 Created)
{
"requests": [
{
"id": "req_001",
"type": "heartRate",
"status": "PENDING"
},
{
"id": "req_002",
"type": "stepCount",
"status": "PENDING"
},
{
"id": "req_003",
"type": "sleepAnalysis",
"status": "PENDING"
}
],
"totalCreated": 3
}
1.3 대기 중인 요청 조회 API (앱용)
- HTTP 메서드: GET
- 경로: /v1/external-health/requests
- Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
- 쿼리 파라미터:
- platform: 플랫폼 지정 (iOS 또는 Android, 필수)
- filterByGrantedPermissions: 승인된 권한 기준 필터링 여부 (선택, 기본 false)
참고: 서버는 요청 조회 시 사용자의 플랫폼 연동 상태 및 권한을 검증합니다. (요구사항 EXH-FR-BE-005-1)
응답 (Response)
- 성공 응답 (200 OK)
{
"requests": [
{
"id": "B437BCAC-CFFF-468C-9A30-5786F74BDB87",
"type": "stepCount",
"startTime": 1764550800000,
"endTime": 1764637200000,
"interval": {
"type": "day",
"value": 1
}
},
{
"id": "BEC32F44-2647-44C8-8C74-1DF64097FA31",
"type": "heartRate",
"startTime": 1764550800000,
"endTime": 1764637200000,
"interval": {
"type": "hour",
"value": 1
}
},
{
"id": "6406D4AE-9C55-40D3-BE25-5EE0AD3859E9",
"type": "sleepAnalysis",
"startTime": 1764550800000,
"endTime": 1764637200000
}
]
}
응답 필드 명세
| Field | Data Type | Required | Comment |
|---|---|---|---|
| requests | Array<Object> | YES | 최소한 empty array |
| request.id | UUID | YES | 요청의 고유 식별자 |
| request.type | String (Enum) | YES | stepCount: quantity, heartRate: quantity, sleepAnalysis: category |
| request.startTime | Int | YES | Unix Epoch Time (milliseconds) |
| request.endTime | Int | YES | Unix Epoch Time (milliseconds) |
| request.interval | Object | NO | 없을 경우 RawData 반환 |
| request.interval.type | String (Enum) | Conditional | year, month, day, hour, minute, second |
| request.interval.value | Int | Conditional | 집계 간격 값 |
- 오류 응답 (403 Forbidden - 권한 없음)
{
"code": 21022,
"message": "PERMISSION_NOT_GRANTED",
"detail": "요청된 데이터 유형에 대한 권한이 승인되지 않았습니다.",
"requiredPermissions": ["heartRate", "sleepAnalysis"],
"grantedPermissions": ["stepCount"]
}
참고:
filterByGrantedPermissions=true파라미터를 사용하면, 권한이 없는 데이터 유형의 요청은 오류 대신 응답에서 제외됩니다.- 앱에서는 이 응답을 받아 각 요청에 해당하는 데이터를 HealthKit/Health Connect SDK를 통해 수집합니다.
1.4 요청 취소 API
- HTTP 메서드: PATCH
- 경로: /v1/external-health/requests/
{requestId}/cancel - Headers:
- Content-Type: application/json
- Authorization: Bearer
{serviceAccountToken}
요청 (Request)
{
"reason": "분석 취소로 인한 요청 취소"
}
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "req_550e8400-e29b-41d4-a716-446655440001",
"status": "CANCELLED",
"cancelledAt": 1702771500000,
"cancelReason": "분석 취소로 인한 요청 취소"
}
데이터 수집 응답 API
데이터 수집 응답 API는 앱에서 수집한 건강 데이터를 서버로 제출하는 기능을 제공합니다.
2.1 수집 데이터 제출 API
- HTTP 메서드: POST
- 경로: /v1/external-health/responses
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}
요청 (Request)
{
"responses": [
{
"requestId": "B437BCAC-CFFF-468C-9A30-5786F74BDB87",
"os": "iOS",
"type": "stepCount",
"startTime": "2025-12-01T10:00:00.000+09:00",
"endTime": "2025-12-02T10:00:00.000+09:00",
"interval": {
"type": "day",
"value": 1
},
"extractedAt": "2025-12-03T07:00:00.000+09:00",
"records": [
{
"startTime": "2025-12-01T10:00:00.000+09:00",
"endTime": "2025-12-02T10:00:00.000+09:00",
"sum": 100,
"unit": "count"
}
]
},
{
"requestId": "BEC32F44-2647-44C8-8C74-1DF64097FA31",
"os": "iOS",
"type": "heartRate",
"startTime": "2025-12-01T10:00:00.000+09:00",
"endTime": "2025-12-02T10:00:00.000+09:00",
"interval": {
"type": "hour",
"value": 1
},
"extractedAt": "2025-12-03T07:00:00.000+09:00",
"records": [
{
"startTime": "2025-12-01T10:00:00.000+09:00",
"endTime": "2025-12-01T11:00:00.000+09:00",
"average": 110.123,
"unit": "count/min"
},
{
"startTime": "2025-12-01T11:00:00.000+09:00",
"endTime": "2025-12-01T12:00:00.000+09:00",
"average": 123.456,
"unit": "count/min"
}
]
},
{
"requestId": "6406D4AE-9C55-40D3-BE25-5EE0AD3859E9",
"os": "iOS",
"type": "sleepAnalysis",
"startTime": "2025-12-01T10:00:00.000+09:00",
"endTime": "2025-12-02T10:00:00.000+09:00",
"extractedAt": "2025-12-03T07:00:00.000+09:00",
"records": [
{
"startTime": "2025-12-01T23:00:00.000+09:00",
"endTime": "2025-12-01T23:05:00.000+09:00",
"category": "inBed"
},
{
"startTime": "2025-12-01T23:05:00.000+09:00",
"endTime": "2025-12-01T23:10:00.000+09:00",
"category": "asleepCore"
}
]
}
]
}
요청 필드 명세
| Field | Data Type | Required | Comment |
|---|---|---|---|
| responses | Array<Object> | YES | 최소한 empty array |
| response.requestId | UUID | YES | GET 요청으로 조회한 요청 ID |
| response.os | String | YES | iOS 또는 Android |
| response.type | String (Enum) | YES | stepCount, heartRate, sleepAnalysis 등 |
| response.startTime | String | YES | ISO8601(ms) + TimeZone |
| response.endTime | String | YES | ISO8601(ms) + TimeZone |
| response.interval | Object | NO | 집계 간격 설정 |
| response.interval.type | String (Enum) | Conditional | year, month, day, hour, minute, second |
| response.interval.value | Int | Conditional | 집계 간격 값 |
| response.extractedAt | String | YES | ISO8601(ms) + TimeZone |
| response.records | Array<Object> | YES | 최소한 empty array |
| response.record.startTime | String | YES | ISO8601(ms) + TimeZone |
| response.record.endTime | String | YES | ISO8601(ms) + TimeZone |
| response.record.sum | Int | NO | stepCount 등 합계 데이터용 |
| response.record.average | Double | NO | heartRate 등 평균 데이터용 |
| response.record.category | String | NO | sleepAnalysis 카테고리 (inBed, asleepCore, asleepDeep, asleepREM, awake) |
| response.record.unit | String | NO | 단위 (count, count/min 등) |
응답 (Response)
- 성공 응답 (200 OK)
{
"results": [
{
"requestId": "B437BCAC-CFFF-468C-9A30-5786F74BDB87",
"status": "COLLECTED",
"processedRecords": 1
},
{
"requestId": "BEC32F44-2647-44C8-8C74-1DF64097FA31",
"status": "COLLECTED",
"processedRecords": 2
},
{
"requestId": "6406D4AE-9C55-40D3-BE25-5EE0AD3859E9",
"status": "COLLECTED",
"processedRecords": 2
}
]
}
- 오류 응답 (400 Bad Request - 유효하지 않은 요청 ID)
{
"code": 21010,
"message": "INVALID_REQUEST_ID",
"detail": "존재하지 않거나 이미 처리된 요청 ID입니다.",
"requestId": "req_invalid"
}
- 오류 응답 (400 Bad Request - 데이터 검증 실패)
{
"code": 21011,
"message": "DATA_VALIDATION_FAILED",
"detail": "수집된 데이터의 유효성 검증에 실패했습니다.",
"validationResult": {
"isValid": false,
"validRecordCount": 20,
"invalidRecordCount": 4,
"errors": [
{
"recordIndex": 5,
"field": "value",
"message": "심박수 값이 유효 범위(30-250)를 벗어났습니다.",
"code": "OUT_OF_RANGE"
}
],
"warnings": []
}
}
- 오류 응답 (409 Conflict - 중복 제출)
{
"code": 21012,
"message": "DUPLICATE_RESPONSE",
"detail": "이미 처리된 요청에 대한 중복 응답입니다.",
"requestId": "req_550e8400-e29b-41d4-a716-446655440001"
}
건강 데이터 조회 API
3.1 건강 데이터 조회 API (기간별)
- HTTP 메서드: GET
- 경로: /v1/external-health/data
- 쿼리 파라미터:
- startDate: 시작일 (YYYY-MM-DD)
- endDate: 종료일 (YYYY-MM-DD)
- types: 데이터 유형 목록 (쉼표 구분, 선택)
- Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"data": [
{
"id": "data_001",
"type": "heartRate",
"dayIndex": 15,
"timestamp": 1702684800000,
"value": 72,
"unit": "bpm",
"verboseValue": "72 bpm",
"aggregationType": "average",
"qualityStatus": "VALID",
"source": "HealthKit",
"createdAt": 1702771200000
},
{
"id": "data_002",
"type": "stepCount",
"dayIndex": 15,
"timestamp": 1702684800000,
"value": 8532,
"unit": "steps",
"verboseValue": "8,532 걸음",
"aggregationType": "sum",
"qualityStatus": "VALID",
"source": "HealthKit",
"createdAt": 1702771200000
}
],
"pagination": {
"total": 50,
"page": 1,
"limit": 20
}
}
3.2 건강 데이터 조회 API (일차 범위별)
- HTTP 메서드: GET
- 경로: /v1/external-health/data/day-index-range
- 쿼리 파라미터:
- startDayIndex: 시작 일차
- endDayIndex: 종료 일차
- types: 데이터 유형 목록 (쉼표 구분, 선택)
- Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"data": [
{
"dayIndex": 15,
"date": "2025-12-01",
"records": [
{
"type": "heartRate",
"averageValue": 72,
"minValue": 58,
"maxValue": 95,
"unit": "bpm",
"recordCount": 24
},
{
"type": "stepCount",
"totalValue": 8532,
"unit": "steps",
"recordCount": 1
}
]
}
]
}
3.3 건강 데이터 요약 조회 API
- HTTP 메서드: GET
- 경로: /v1/external-health/data/summary
- 쿼리 파라미터:
- startDate: 시작일 (YYYY-MM-DD)
- endDate: 종료일 (YYYY-MM-DD)
- Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"startDate": "2025-12-01",
"endDate": "2025-12-07",
"dayIndexRange": {
"start": 15,
"end": 21
},
"summaries": {
"heartRate": {
"totalRecords": 168,
"validRecords": 165,
"average": 72.5,
"min": 55,
"max": 110,
"unit": "bpm"
},
"stepCount": {
"totalRecords": 7,
"validRecords": 7,
"sum": 52340,
"average": 7477,
"min": 4230,
"max": 12500,
"unit": "steps"
}
},
"sleepSummary": {
"totalNights": 7,
"avgSleepDuration": 420,
"avgSleepEfficiency": 0.88,
"avgRemPercentage": 22.5,
"avgDeepPercentage": 18.3
}
}
플랫폼 연동 API
4.1 플랫폼 연동 목록 조회 API
- HTTP 메서드: GET
- 경로: /v1/external-health/platforms
- Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"connections": [
{
"id": "conn_001",
"platform": "iOS",
"status": "CONNECTED",
"permissions": {
"dataTypes": ["heartRate", "stepCount", "sleepAnalysis", "heartRateVariability"],
"lastUpdatedAt": 1702684800000
},
"lastSyncAt": 1702771200000,
"lastSyncStatus": "SUCCESS",
"connectedAt": 1700000000000
}
]
}
4.2 플랫폼 연동 API
- HTTP 메서드: POST
- 경로: /v1/external-health/platforms/connect
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}
요청 (Request)
{
"platform": "iOS",
"permissions": ["heartRate", "stepCount", "sleepAnalysis", "heartRateVariability"],
"deviceId": "device_abc123",
"deviceModel": "iPhone 15 Pro",
"osVersion": "17.2"
}
응답 (Response)
- 성공 응답 (201 Created)
{
"id": "conn_001",
"platform": "iOS",
"status": "CONNECTED",
"permissions": {
"dataTypes": ["heartRate", "stepCount", "sleepAnalysis", "heartRateVariability"],
"lastUpdatedAt": 1702771200000
},
"connectedAt": 1702771200000
}
4.3 플랫폼 연동 해제 API
- HTTP 메서드: POST
- 경로: /v1/external-health/platforms/disconnect
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}
요청 (Request)
{
"platform": "iOS"
}
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "conn_001",
"platform": "iOS",
"status": "DISCONNECTED",
"disconnectedAt": 1702771500000
}
4.4 플랫폼 권한 업데이트 API
- HTTP 메서드: PATCH
- 경로: /v1/external-health/platforms/permissions
- Headers:
- Content-Type: application/json
- Authorization: Bearer
{accessToken}
요청 (Request)
{
"platform": "iOS",
"permissions": ["heartRate", "stepCount", "sleepAnalysis"]
}
응답 (Response)
- 성공 응답 (200 OK)
{
"id": "conn_001",
"platform": "iOS",
"permissions": {
"dataTypes": ["heartRate", "stepCount", "sleepAnalysis"],
"lastUpdatedAt": 1702771600000
}
}
외부 수면 데이터 API
5.1 외부 수면 데이터 조회 API
- HTTP 메서드: GET
- 경로: /v1/external-health/sleep-data
- 쿼리 파라미터:
- startDate: 시작일 (YYYY-MM-DD)
- endDate: 종료일 (YYYY-MM-DD)
- Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"sleepData": [
{
"id": "sleep_001",
"dayIndex": 15,
"sleepStart": 1702677600000,
"sleepEnd": 1702702800000,
"totalSleepMinutes": 420,
"sleepEfficiency": 0.88,
"timeInBed": 477,
"awakeTime": 57,
"sleepStages": [
{
"stage": "LIGHT",
"startTime": 1702677600000,
"endTime": 1702682400000,
"durationMinutes": 80
},
{
"stage": "DEEP",
"startTime": 1702682400000,
"endTime": 1702689600000,
"durationMinutes": 120
},
{
"stage": "REM",
"startTime": 1702689600000,
"endTime": 1702696800000,
"durationMinutes": 120
},
{
"stage": "LIGHT",
"startTime": 1702696800000,
"endTime": 1702702800000,
"durationMinutes": 100
}
],
"remSleepMinutes": 120,
"lightSleepMinutes": 180,
"deepSleepMinutes": 120,
"qualityStatus": "VALID",
"source": "HealthKit",
"createdAt": 1702771200000
}
]
}
데이터 관리 API
6.1 사용자 데이터 내보내기 API
- HTTP 메서드: GET
- 경로: /v1/external-health/users/me/data-export
- 쿼리 파라미터:
- format: 내보내기 형식 (JSON 또는 CSV, 기본 JSON)
- Headers:
- Authorization: Bearer
{accessToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"exportId": "export_001",
"status": "PROCESSING",
"format": "JSON",
"requestedAt": 1702771200000,
"estimatedCompletionTime": 1702771500000
}
참고: 대용량 데이터의 경우 비동기 처리되며, 완료 시 다운로드 URL이 제공됩니다.
6.2 관리자 - 사용자 데이터 조회 API
- HTTP 메서드: GET
- 경로: /v1/external-health/admin/users/
{userId}/data - 쿼리 파라미터:
- startDate: 시작일 (YYYY-MM-DD)
- endDate: 종료일 (YYYY-MM-DD)
- types: 데이터 유형 목록 (쉼표 구분, 선택)
- Headers:
- Authorization: Bearer
{adminToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"data": [
{
"type": "heartRate",
"records": [...]
}
],
"accessedAt": 1702771200000,
"accessedBy": "admin_001"
}
6.3 관리자 - 사용자 데이터 삭제 API
- HTTP 메서드: DELETE
- 경로: /v1/external-health/admin/users/
{userId}/data - Headers:
- Authorization: Bearer
{adminToken}
- Authorization: Bearer
응답 (Response)
- 성공 응답 (200 OK)
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"deletedRecords": {
"healthData": 1250,
"sleepData": 45,
"requests": 120,
"responses": 120,
"platformConnections": 1
},
"deletedAt": 1702771200000,
"deletedBy": "admin_001"
}
오류 코드
참고: External Health 도메인은 21000-21099 범위의 에러 코드를 사용합니다. 전체 도메인 에러 코드 맵은 error-code-registry.md를 참조하세요.
| 코드 | 메시지 | 설명 |
|---|---|---|
| 21000 | SERVER_ERROR | 서버 내부 오류 |
| 21001 | INVALID_DATA_TYPE | 지원하지 않는 데이터 유형 |
| 21002 | INVALID_INTERVAL | 유효하지 않은 집계 간격 |
| 21003 | INVALID_TIME_RANGE | 유효하지 않은 시간 범위 |
| 21004 | USER_NOT_FOUND | 사용자를 찾을 수 없음 |
| 21010 | INVALID_REQUEST_ID | 유효하지 않은 요청 ID |
| 21011 | DATA_VALIDATION_FAILED | 데이터 유효성 검증 실패 |
| 21012 | DUPLICATE_RESPONSE | 중복 응답 제출 |
| 21013 | REQUEST_EXPIRED | 만료된 요청에 대한 응답 |
| 21014 | REQUEST_ALREADY_PROCESSED | 이미 처리된 요청 |
| 21021 | PLATFORM_ALREADY_CONNECTED | 플랫폼이 이미 연동됨 |
| 21022 | PERMISSION_NOT_GRANTED | 권한이 승인되지 않음 |
| 21030 | DATA_NOT_FOUND | 데이터를 찾을 수 없음 |
| 21031 | DATA_OUT_OF_RANGE | 데이터가 유효 범위를 벗어남 |
| 21032 | DATA_ANOMALY_DETECTED | 데이터 이상치 감지 |
| 21040 | EXPORT_IN_PROGRESS | 데이터 내보내기가 이미 진행 중 |
| 21041 | EXPORT_FAILED | 데이터 내보내기 실패 |
| 21050 | UNAUTHORIZED_ACCESS | 권한 없는 접근 |
| 21051 | ADMIN_ACCESS_REQUIRED | 관리자 권한 필요 |
변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-12-15 | claude@weltcorp.com | 최초 작성 |