k-skill/docs/features/k-skill-proxy.md
Jeffrey (Dongkyu) Kim e6d7072e93
Feature/#274 (#277)
* Add Seoul Bike live station lookup

Expose narrow Seoul Open Data proxy surfaces for realtime bike availability, station master pages, and coordinate-based nearby lookups while keeping the upstream key server-side. Add a single Python skill entrypoint plus docs so agents can answer last-mile bike and dock availability questions.

Constraint: Issue #274 requires , TDD, three proxy routes, branch feature/#274, and PR to dev.
Rejected: Client-side Seoul OpenAPI key handling | would leak upstream credentials and violate existing proxy patterns.
Confidence: high
Scope-risk: moderate
Directive: Keep these routes read-only; do not add rental/booking mutations or user-key requirements.
Tested: node --test packages/k-skill-proxy/test/server.test.js --test-name-pattern 'seoul bike'; PYTHONPATH=.:scripts python3 -m unittest scripts.test_seoul_bike; local fake-proxy smoke run; PATH="/Users/jeffrey/.pyenv/versions/3.11.9/bin:/Users/jeffrey/.codex/tmp/arg0/codex-arg08RBix6:/opt/homebrew/lib/node_modules/@openai/codex/node_modules/@openai/codex-darwin-arm64/vendor/aarch64-apple-darwin/path:/Users/jeffrey/.cmuxterm/omo-bin:/opt/homebrew/share/android-commandlinetools/platform-tools:/opt/homebrew/share/android-commandlinetools/emulator:/opt/homebrew/share/android-commandlinetools/cmdline-tools/latest/bin:/Users/jeffrey/.local/bin:/Users/jeffrey/.bun/bin:/opt/homebrew/opt/node@22/bin:/opt/homebrew/opt/openjdk@21/bin:/opt/homebrew/opt/postgresql@18/bin:/Users/jeffrey/.jenv/shims:/Users/jeffrey/.jenv/bin:/opt/homebrew/opt/imagemagick/bin:/opt/homebrew/Cellar/pyenv-virtualenv/1.4.0/shims:/Users/jeffrey/.pyenv/shims:/opt/homebrew/opt/openssl@3/bin:/Users/jeffrey/.rbenv/shims:/Users/jeffrey/.rbenv/bin:/Users/jeffrey/google-cloud-sdk/bin:/Applications/cmux.app/Contents/Resources/bin:/Users/jeffrey/Library/pnpm:/Users/jeffrey/.nvm/versions/node/v24.13.0/bin:/Users/jeffrey/.cops/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pmk/env/global/bin:/Library/Apple/usr/bin:/Library/TeX/texbin:/Users/jeffrey/.cargo/bin:/Users/jeffrey/Library/Application Support/JetBrains/Toolbox/scripts:/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin:/Users/jeffrey/xcode-projects/marshroom/cli" npm run ci.
Not-tested: Live hosted Seoul Open Data request with production SEOUL_OPEN_API_KEY.

* Prevent Seoul Bike upstream errors from masquerading as empty availability

Constraint: Seoul Open API can return application-level error JSON with HTTP 200, so proxy routes must inspect RESULT envelopes before caching or normalizing rows.
Rejected: Treating missing rentBikeStatus.row as an empty success | it masks quota/service failures and caches false no-station results.
Confidence: high
Scope-risk: narrow
Directive: Preserve non-cacheable proxy error behavior for Seoul Open API semantic failures across realtime, stations, and nearby routes.
Tested: node --test packages/k-skill-proxy/test/server.test.js --test-name-pattern 'seoul bike'; PYTHONPATH=.:scripts python3 -m unittest scripts.test_seoul_bike; local fake-proxy seoul_bike.py nearby smoke; PATH="/Users/jeffrey/.pyenv/versions/3.11.9/bin:/Users/jeffrey/.codex/tmp/arg0/codex-arg0j0fIum:/opt/homebrew/lib/node_modules/@openai/codex/node_modules/@openai/codex-darwin-arm64/vendor/aarch64-apple-darwin/path:/Users/jeffrey/.cmuxterm/omo-bin:/opt/homebrew/share/android-commandlinetools/platform-tools:/opt/homebrew/share/android-commandlinetools/emulator:/opt/homebrew/share/android-commandlinetools/cmdline-tools/latest/bin:/Users/jeffrey/.local/bin:/Users/jeffrey/.bun/bin:/opt/homebrew/opt/node@22/bin:/opt/homebrew/opt/openjdk@21/bin:/opt/homebrew/opt/postgresql@18/bin:/Users/jeffrey/.jenv/shims:/Users/jeffrey/.jenv/bin:/opt/homebrew/opt/imagemagick/bin:/opt/homebrew/Cellar/pyenv-virtualenv/1.4.0/shims:/Users/jeffrey/.pyenv/shims:/opt/homebrew/opt/openssl@3/bin:/Users/jeffrey/.rbenv/shims:/Users/jeffrey/.rbenv/bin:/Users/jeffrey/google-cloud-sdk/bin:/Applications/cmux.app/Contents/Resources/bin:/Users/jeffrey/Library/pnpm:/Users/jeffrey/.nvm/versions/node/v24.13.0/bin:/Users/jeffrey/.cops/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pmk/env/global/bin:/Library/Apple/usr/bin:/Library/TeX/texbin:/Users/jeffrey/.cargo/bin:/Users/jeffrey/Library/Application Support/JetBrains/Toolbox/scripts:/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin:/Users/jeffrey/xcode-projects/marshroom/cli" npm run ci; architect review APPROVED.
Not-tested: Live Seoul Open API error response from production service.

* Reject ambiguous Seoul Bike integer input

Tighten the public Seoul Bike query boundary so malformed integer strings cannot be partially parsed into valid requests.

Constraint: PR #277 review found parseInt accepted partially numeric query values on Seoul Bike routes.\nRejected: Keep parseInt with bounds checks | bounds still allow misleading values like 10abc and 1.5.\nConfidence: high\nScope-risk: narrow\nDirective: Keep Seoul Bike public query aliases strict; do not reintroduce partial numeric parsing.\nTested: node --test packages/k-skill-proxy/test/server.test.js --test-name-pattern 'seoul bike'; PYTHONPATH=.:scripts python3 -m unittest scripts.test_seoul_bike; explicit app.inject invalid-query smoke; PATH="/Users/jeffrey/.pyenv/versions/3.11.9/bin:/Users/jeffrey/.codex/tmp/arg0/codex-arg0uv50Mt:/opt/homebrew/lib/node_modules/@openai/codex/node_modules/@openai/codex-darwin-arm64/vendor/aarch64-apple-darwin/path:/Users/jeffrey/.cmuxterm/omo-bin:/opt/homebrew/share/android-commandlinetools/platform-tools:/opt/homebrew/share/android-commandlinetools/emulator:/opt/homebrew/share/android-commandlinetools/cmdline-tools/latest/bin:/Users/jeffrey/.local/bin:/Users/jeffrey/.bun/bin:/opt/homebrew/opt/node@22/bin:/opt/homebrew/opt/openjdk@21/bin:/opt/homebrew/opt/postgresql@18/bin:/Users/jeffrey/.jenv/shims:/Users/jeffrey/.jenv/bin:/opt/homebrew/opt/imagemagick/bin:/opt/homebrew/Cellar/pyenv-virtualenv/1.4.0/shims:/Users/jeffrey/.pyenv/shims:/opt/homebrew/opt/openssl@3/bin:/Users/jeffrey/.rbenv/shims:/Users/jeffrey/.rbenv/bin:/Users/jeffrey/google-cloud-sdk/bin:/Applications/cmux.app/Contents/Resources/bin:/Users/jeffrey/Library/pnpm:/Users/jeffrey/.nvm/versions/node/v24.13.0/bin:/Users/jeffrey/.cops/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pmk/env/global/bin:/Library/Apple/usr/bin:/Library/TeX/texbin:/Users/jeffrey/.cargo/bin:/Users/jeffrey/Library/Application Support/JetBrains/Toolbox/scripts:/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin:/Users/jeffrey/xcode-projects/marshroom/cli" npm run ci\nNot-tested: live hosted Seoul Open API traffic

* Protect hosted Seoul Bike proxy secrets

Sanitize Seoul Bike upstream fetch and parse failures before they can reach the global error handler, and reject blank nearby coordinates before JavaScript can coerce them to zero.\n\nConstraint: PR #277 round-3 review found server-side Seoul Open API keys could leak through exception messages containing keyed upstream URLs.\nRejected: Letting the global error handler format Seoul Bike upstream exceptions | it echoes exception messages and can expose the hosted proxy API key.\nConfidence: high\nScope-risk: narrow\nDirective: Keep server-side API-key-bearing upstream URLs out of client-visible error messages and logs for hosted no-user-key routes.\nTested: node --test packages/k-skill-proxy/test/server.test.js --test-name-pattern 'seoul bike'; PYTHONPATH=.:scripts python3 -m unittest scripts.test_seoul_bike; explicit app.inject smoke for sanitized Seoul Bike failures and blank coordinates; local fake-proxy seoul-bike nearby smoke; PATH="/Users/jeffrey/.pyenv/versions/3.11.9/bin:/Users/jeffrey/.codex/tmp/arg0/codex-arg0mxZmWx:/opt/homebrew/lib/node_modules/@openai/codex/node_modules/@openai/codex-darwin-arm64/vendor/aarch64-apple-darwin/path:/Users/jeffrey/.cmuxterm/omo-bin:/opt/homebrew/share/android-commandlinetools/platform-tools:/opt/homebrew/share/android-commandlinetools/emulator:/opt/homebrew/share/android-commandlinetools/cmdline-tools/latest/bin:/Users/jeffrey/.local/bin:/Users/jeffrey/.bun/bin:/opt/homebrew/opt/node@22/bin:/opt/homebrew/opt/openjdk@21/bin:/opt/homebrew/opt/postgresql@18/bin:/Users/jeffrey/.jenv/shims:/Users/jeffrey/.jenv/bin:/opt/homebrew/opt/imagemagick/bin:/opt/homebrew/Cellar/pyenv-virtualenv/1.4.0/shims:/Users/jeffrey/.pyenv/shims:/opt/homebrew/opt/openssl@3/bin:/Users/jeffrey/.rbenv/shims:/Users/jeffrey/.rbenv/bin:/Users/jeffrey/google-cloud-sdk/bin:/Applications/cmux.app/Contents/Resources/bin:/Users/jeffrey/Library/pnpm:/Users/jeffrey/.nvm/versions/node/v24.13.0/bin:/Users/jeffrey/.cops/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pmk/env/global/bin:/Library/Apple/usr/bin:/Library/TeX/texbin:/Users/jeffrey/.cargo/bin:/Users/jeffrey/Library/Application Support/JetBrains/Toolbox/scripts:/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin:/Users/jeffrey/xcode-projects/marshroom/cli" npm run ci.\nNot-tested: Live Seoul Open API network failure from production Cloud Run.
2026-05-22 13:54:36 +09:00

13 KiB

k-skill 프록시 서버 가이드

이 기능으로 할 수 있는 일

  • AirKorea 같은 무료/공공 API key를 서버에만 보관
  • k-skill 클라이언트는 프록시만 호출
  • 캐시, 인증, rate limit, 로깅을 한곳에서 통제

기본 구조

client/skill -> k-skill-proxy -> upstream public API

현재 기본 엔드포인트는 아래와 같습니다.

  • GET /health
  • GET /v1/fine-dust/report
  • GET /v1/korea-weather/forecast
  • GET /v1/seoul-subway/arrival
  • GET /v1/seoul-density/citydata (서울 실시간 도시데이터 핫스팟 혼잡도/추정 인구, SEOUL_OPEN_API_KEY)
  • GET /v1/seoul-bike/realtime (서울 따릉이 실시간 대여정보 bikeList, SEOUL_OPEN_API_KEY)
  • GET /v1/seoul-bike/stations (서울 따릉이 대여소 마스터 tbCycleStationInfo, SEOUL_OPEN_API_KEY)
  • GET /v1/seoul-bike/nearby (좌표 주변 따릉이 실시간 대여소 필터링, SEOUL_OPEN_API_KEY)
  • GET /v1/han-river/water-level
  • GET /v1/household-waste/info (생활쓰레기 배출정보, DATA_GO_KR_API_KEY; 쿼리 pageNo·numOfRows 필수, 값 1·100)
  • GET /v1/mfds/drug-safety/lookup (식약처 의약품개요정보 + 안전상비의약품 정보, DATA_GO_KR_API_KEY)
  • GET /v1/mfds/food-safety/search (식약처 부적합 식품 + 식품안전나라 회수 정보, DATA_GO_KR_API_KEY, 선택적 FOODSAFETYKOREA_API_KEY)
  • GET /v1/korean-stock/search
  • GET /v1/korean-stock/base-info
  • GET /v1/korean-stock/trade-info
  • GET /v1/naver-shopping/search (네이버 검색 Open API 쇼핑 검색 우선, 키가 없으면 공개 BFF JSON 기반 상품/가격 후보 조회)
  • GET /v1/opinet/around
  • GET /v1/opinet/detail
  • GET /v1/neis/school-search (나이스 학교기본정보, KEDU_INFO_KEY)
  • GET /v1/neis/school-meal (나이스 급식식단정보, KEDU_INFO_KEY)
  • GET /v1/data4library/library-search (도서관 정보나루 정보공개 도서관 조회, DATA4LIBRARY_AUTH_KEY)
  • GET /v1/data4library/book-search (도서관 정보나루 도서 검색, DATA4LIBRARY_AUTH_KEY)
  • GET /v1/data4library/book-detail (도서관 정보나루 도서 상세 조회, DATA4LIBRARY_AUTH_KEY)
  • GET /v1/data4library/libraries-by-book (도서 소장 도서관 조회, DATA4LIBRARY_AUTH_KEY)
  • GET /v1/data4library/book-exists (도서관별 도서 소장여부, DATA4LIBRARY_AUTH_KEY)
  • GET /v1/kstartup/business-info (창업진흥원 K-Startup 통합공고 지원사업 정보, DATA_GO_KR_API_KEY)
  • GET /v1/kstartup/announcements (창업진흥원 K-Startup 지원사업 공고 정보, DATA_GO_KR_API_KEY)
  • GET /v1/kstartup/contents (창업진흥원 K-Startup 창업 콘텐츠 정보, DATA_GO_KR_API_KEY)
  • GET /v1/kstartup/statistics (창업진흥원 K-Startup 통계보고서 정보, DATA_GO_KR_API_KEY)
  • GET /B552584/:service/:operation (허용된 AirKorea route passthrough)

권장 환경변수

클라이언트(스킬) 쪽:

  • 일반 hosted client는 KSKILL_PROXY_BASE_URL을 unset/empty로 비워 두면 hosted https://k-skill-proxy.nomadamas.org를 기본값으로 사용합니다.
  • KSKILL_PROXY_BASE_URL=https://your-proxy.example.com은 self-host 또는 alternate proxy를 명시적으로 쓰는 경우에만 설정하는 override 예시입니다.

프록시 서버 쪽:

  • AIR_KOREA_OPEN_API_KEY=...
  • KMA_OPEN_API_KEY=...
  • SEOUL_OPEN_API_KEY=...
  • HRFCO_OPEN_API_KEY=...
  • OPINET_API_KEY=...
  • DATA_GO_KR_API_KEY=...
  • FOODSAFETYKOREA_API_KEY=... (선택: 식품안전나라 회수 live 결과, 없으면 sample fallback)
  • KEDU_INFO_KEY=... (나이스 교육정보 개방 포털 Open API 인증키)
  • DATA4LIBRARY_AUTH_KEY=... (도서관 정보나루 Open API 인증키)
  • KRX_API_KEY=...
  • NAVER_SEARCH_CLIENT_ID=..., NAVER_SEARCH_CLIENT_SECRET=... (선택: 네이버 검색 Open API 쇼핑 검색)
  • KSKILL_PROXY_PORT=4020

프로덕션 배포 구조

프로덕션 proxy 서버는 Google Cloud Run에서 운영한다.

  • GCP project: k-skill-proxy
  • Region: asia-northeast1 (도쿄)
  • Cloud Run service: k-skill-proxy
  • 공개 도메인: k-skill-proxy.nomadamas.org (Cloud Run domain mapping)
  • 컨테이너 이미지 정의: packages/k-skill-proxy/Dockerfile
  • 시크릿(upstream API key): GCP Secret Manager에 보관, Cloud Run runtime에 주입

자동 배포 (GitHub Actions)

main 브랜치에 push/merge되면 .github/workflows/deploy-k-skill-proxy.yml 워크플로가 실행되어 다음 순서로 동작한다.

  1. Workload Identity Federation으로 GCP 인증
  2. packages/k-skill-proxy/Dockerfile로 이미지 빌드
  3. Artifact Registry (asia-northeast1-docker.pkg.dev/k-skill-proxy/k-skill/k-skill-proxy:<sha>)에 push
  4. Cloud Run service k-skill-proxy 재배포 (Secret Manager 시크릿 + 런타임 환경변수 주입)
  5. 직접 Cloud Run URL과 https://k-skill-proxy.nomadamas.org/health smoke test

따라서 main에 merge되어야 프로덕션에 반영된다. dev 브랜치 변경은 프로덕션에 영향 없음.

배포 상태와 로그는 GitHub Actions의 "Deploy k-skill-proxy to Cloud Run" 워크플로 실행 페이지와 GCP Console의 Cloud Run revision/log에서 확인한다.

초기 셋업 (운영자 1회 수행)

WIF pool/provider, deploy service account, Secret Manager 시크릿 생성 등 1회성 GCP 셋업 절차와 GitHub repository secrets/variables 등록 방법은 docs/deploy-k-skill-proxy.md에 정리되어 있다.

기본 공개 정책

  • 이 프록시는 무료 API만 붙인다.
  • 기본값은 무인증 공개 endpoint 다.
  • 대신 read-only / allowlisted endpoint / cache / rate limit 을 유지한다.
  • 문제가 생기면 그때 인증이나 더 강한 방어를 덧붙인다.

사용법

추가 client API 레이어는 불필요합니다. 필요한 쿼리를 그대로 프록시에 넣으면 되고, 프록시가 upstream API key 만 서버에서 주입합니다.

요약 endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/fine-dust/report' \
  --data-urlencode 'regionHint=서울 강남구'

서울 지하철 도착정보 endpoint:

BASE="${KSKILL_PROXY_BASE_URL:-https://k-skill-proxy.nomadamas.org}"
curl -fsS --get "${BASE}/v1/seoul-subway/arrival" \
  --data-urlencode 'stationName=강남'

서울 실시간 혼잡도 endpoint:

BASE="${KSKILL_PROXY_BASE_URL:-https://k-skill-proxy.nomadamas.org}"
curl -fsS --get "${BASE}/v1/seoul-density/citydata" \
  --data-urlencode 'area=강남역'

# 서울 따릉이 주변 대여소
curl -fsS --get "${BASE}/v1/seoul-bike/nearby" \
  --data-urlencode 'lat=37.5717' \
  --data-urlencode 'lon=126.9763' \
  --data-urlencode 'radius_m=500'

한국 날씨 endpoint:

BASE="${KSKILL_PROXY_BASE_URL:-https://k-skill-proxy.nomadamas.org}"
curl -fsS --get "${BASE}/v1/korea-weather/forecast" \
  --data-urlencode 'lat=37.5665' \
  --data-urlencode 'lon=126.9780'

한강 수위 정보 endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/han-river/water-level' \
  --data-urlencode 'stationName=한강대교'

이 endpoint 는 내부적으로 HRFCO waterlevel/info.json 으로 관측소를 찾고, waterlevel/list/10M/{WLOBSCD}.json 으로 최신 10분 수위/유량을 가져옵니다.

Opinet 근처 주유소 가격 endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/opinet/around' \
  --data-urlencode 'x=313680' \
  --data-urlencode 'y=545015' \
  --data-urlencode 'radius=1500' \
  --data-urlencode 'prodcd=B027'

Opinet 주유소 상세 endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/opinet/detail' \
  --data-urlencode 'id=A0009905'

나이스 학교 검색·급식 endpoint (학교 급식 식단 스킬에서 사용):

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/neis/school-search' \
  --data-urlencode 'educationOffice=서울특별시교육청' \
  --data-urlencode 'schoolName=미래초등학교'
curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/neis/school-meal' \
  --data-urlencode 'educationOfficeCode=B10' \
  --data-urlencode 'schoolCode=7010123' \
  --data-urlencode 'mealDate=20260410'

생활쓰레기 배출정보 endpoint. 쿼리에 pageNonumOfRows를 반드시 포함하고, 값은 각각 1, **100**만 허용한다(page_no / num_of_rows 동일). 누락·다른 값·숫자만이 아닌 문자열이면 400(upstream 미호출):

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/household-waste/info' \
  --data-urlencode 'cond[SGG_NM::LIKE]=강남구' \
  --data-urlencode 'pageNo=1' \
  --data-urlencode 'numOfRows=100'

의약품 안전 체크 endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/mfds/drug-safety/lookup' \
  --data-urlencode 'itemName=타이레놀' \
  --data-urlencode 'itemName=판콜' \
  --data-urlencode 'limit=5'

식품 안전 체크 endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/mfds/food-safety/search' \
  --data-urlencode 'query=김밥' \
  --data-urlencode 'limit=5'

KOSIS 통계 조회 endpoint (KOSIS_API_KEY 필요, caller apiKey는 무시하고 서버 쪽 키를 주입):

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/kosis/search' \
  --data-urlencode 'q=1인 가구' \
  --data-urlencode 'limit=3'

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/kosis/meta' \
  --data-urlencode 'tableId=DT_1JC1501' \
  --data-urlencode 'metaType=ITM'

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/kosis/data' \
  --data-urlencode 'tableId=DT_1JC1501' \
  --data-urlencode 'prdSe=Y' \
  --data-urlencode 'start=2020' \
  --data-urlencode 'end=2023' \
  --data-urlencode 'objL1=ALL'

Kakao Local geocoding endpoint (KAKAO_REST_API_KEY 필요, caller apiKey는 무시하고 서버 쪽 키를 주입):

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/kakao-local/geocode' \
  --data-urlencode 'q=서울역' \
  --data-urlencode 'limit=1'

도서관 정보나루 도서 검색 endpoint (DATA4LIBRARY_AUTH_KEY 필요):

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/data4library/book-search' \
  --data-urlencode 'keyword=역사' \
  --data-urlencode 'pageNo=1' \
  --data-urlencode 'pageSize=10'

도서 상세/소장 조회 endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/data4library/book-detail' \
  --data-urlencode 'isbn13=9788971998557' \
  --data-urlencode 'loaninfoYN=Y'

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/data4library/libraries-by-book' \
  --data-urlencode 'isbn=9788971998557' \
  --data-urlencode 'region=11'

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/data4library/book-exists' \
  --data-urlencode 'libraryCode=111001' \
  --data-urlencode 'isbn13=9788971998557'

프록시는 caller가 넘긴 authKey/format을 무시하고 서버 쪽 DATA4LIBRARY_AUTH_KEYformat=json을 주입한다.

네이버 쇼핑 가격비교 endpoint (NAVER_SEARCH_CLIENT_ID/NAVER_SEARCH_CLIENT_SECRET이 있으면 공식 Search API 우선):

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/naver-shopping/search' \
  --data-urlencode 'q=에어팟 프로 2세대' \
  --data-urlencode 'limit=10'

키가 없는 no-key fallback은 search.shopping.naver.com/search/all HTML 페이지 대신 ns-portal.shopping.naver.com/api/v2/shopping-paged-slot?query=<검색어>&source=shp_gui 공개 JSON path를 사용한다. page는 BFF에 전달한 뒤 해당 페이지 카드만 정규화하고, no-key price_asc/price_dsc/review 정렬은 선택된 BFF 페이지 안에서 로컬 적용한다. BFF에는 날짜 필드가 없어 no-key date 요청은 meta.sort_applied: "unsupported"로 표시한다.

한국 주식 검색 endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/korean-stock/search' \
  --data-urlencode 'q=삼성전자' \
  --data-urlencode 'bas_dd=20260408'

한국 주식 기본정보 endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/korean-stock/base-info' \
  --data-urlencode 'market=KOSPI' \
  --data-urlencode 'code=005930' \
  --data-urlencode 'bas_dd=20260408'

AirKorea passthrough endpoint:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/B552584/ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty' \
  --data-urlencode 'returnType=json' \
  --data-urlencode 'numOfRows=1' \
  --data-urlencode 'pageNo=1' \
  --data-urlencode 'stationName=강남구' \
  --data-urlencode 'dataTerm=DAILY' \
  --data-urlencode 'ver=1.4'

주의할 점

  • upstream key는 프록시 서버에서만 관리합니다.
  • 한국 주식 route도 사용자에게 KRX_API_KEY 를 배포하지 않습니다.
  • client 쪽에는 upstream API key를 배포하지 않습니다.
  • 도서관 정보나루 route도 사용자에게 DATA4LIBRARY_AUTH_KEY 를 배포하지 않습니다.
  • self-host proxy 운영자는 동일 route를 local/self-host URL 로도 검증합니다.