전체 문서 탐색

ETF API 레퍼런스: ETF와 펀드

ETF와 뮤추얼 펀드의 가격, NAV, 이력, 분배금

개요

ETF와 뮤추얼 펀드의 시세, 가격 이력, 분배금, 프로필, 검색을 제공합니다. 모든 요청에 Bearer 키가 필요하며, REST와 MCP는 하나의 크레딧 잔액을 함께 사용합니다.

ETF id는 ARCX:SPY처럼 해당 종목 id입니다. 뮤추얼 펀드 id는 FUND, 콜론, 티커 순서로 쓰며 FUND:VFIAX가 그 예입니다. SPY처럼 티커만 보내는 경우에도 미국 종목 하나를 가리키면 사용할 수 있습니다. 펀드 경로에 주식 id를 보내면 404 not_found가 반환되고, 주식 경로에 펀드 id를 보내면 301로 이 경로로 이동합니다.

ETF에는 가격이 있습니다. 뮤추얼 펀드에는 하루에 한 번 순자산가치(NAV)가 있으며 nav, previous_nav, date 필드에 담깁니다. 가격 응답의 type 필드로 어느 쪽인지 구분할 수 있습니다.

기본 URL: https://api.narwhalapi.com. MCP 도구: funds, with one action 를 아래 각 라우트에 대응해 둡니다.

모든 계정에 제공되는 것

항목모든 계정
ETF 최신 가격라이브
뮤추얼 펀드 NAV최신 NAV
일봉과 과거 분배금전체 이력
1분봉 (ETF만 해당)포함
검색 및 프로필포함

확인 요금 페이지에서 호출당 비용을 확인할 수 있습니다. 라우트에 별도 안내가 없으면 요청은 해당 API의 가격으로 청구됩니다.

  • 뮤추얼 펀드 NAV는 장 마감 시점의 값이며 지연되지 않습니다. 다음 영업일보다 오래되면 stale로 표시됩니다.
  • 뮤추얼 펀드에는 1분봉이 없습니다. 1분봉을 요청하면 400 invalid_interval이 반환됩니다.
  • 뮤추얼 펀드의 일봉은 NAV입니다. 시가, 고가, 저가, 종가가 모두 같은 값이고 거래량은 없습니다.
  • 분배금의 kind는 출처에서 값을 제공하기 전까지 생략됩니다.

엔드포인트

모든 경로는 GET이며, 키를 다음 헤더에 담아 보내야 합니다: Authorization: Bearer 헤더입니다. 예시는 응답의 형태를 보여 줄 뿐이며 실시간 데이터가 아닙니다.

펀드 하나의 프로필

GET /v1/funds/{id}

자체 심볼 목록에 있는 그대로 펀드의 심볼, 이름, 유형(etf 또는 mutual_fund), 거래소(ETF만 해당), 국가, 통화를 반환합니다. 모든 계정에서 사용할 수 있습니다. 알 수 없는 필드는 생략됩니다.

MCP: 도구 funds, action profile.

매개변수

매개변수위치필수유형의미
id경로예문자열펀드 id입니다. ETF는 종목 id로, 거래소의 네 글자 코드, 콜론, 티커 순서입니다(ARCX:SPY). 뮤추얼 펀드는 FUND, 콜론, 티커 순서입니다(FUND:VFIAX). SPY처럼 티커만 보내는 경우에도 미국 종목 하나를 가리키면 사용할 수 있으며, 응답에는 표준 id가 담깁니다.

응답 필드

필드유형전송의미
id문자열항상표준 펀드 id입니다.
symbol문자열항상펀드의 티커입니다.
name문자열항상자체 심볼 목록에 있는 그대로의 이름입니다.
typeetf, mutual_fund 중 하나항상상품의 종류입니다.
mic문자열선택거래소의 네 글자 코드입니다. 뮤추얼 펀드는 거래소가 없으므로 생략됩니다.
country문자열선택펀드의 국가이며 세 글자 코드입니다.
currency문자열항상가격의 통화입니다.
요청
curl -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/funds/ARCX:SPY"
응답 예시
{
  "id": "ARCX:SPY",
  "symbol": "SPY",
  "name": "SPDR S&P 500 ETF Trust",
  "type": "etf",
  "mic": "ARCX",
  "country": "USA",
  "currency": "USD"
}

펀드 하나의 최신 가격

GET /v1/funds/{id}/price

ETF는 주식 가격 형식에 type: etf를 더한 최종 가격을, 뮤추얼 펀드는 최신 NAV를 반환합니다(type: mutual_fund: nav, previous_nav, change, change_percent, NAV 기준일 date. 장 마감 시점의 값이며 지연되지 않고, 다음 영업일보다 오래되면 stale이 됩니다). change_percent는 퍼센트 단위입니다. 주식 id는 404 not_found입니다.

MCP: 도구 funds, action price.

매개변수

매개변수위치필수유형의미
id경로예문자열펀드 id입니다. ETF는 종목 id로, 거래소의 네 글자 코드, 콜론, 티커 순서입니다(ARCX:SPY). 뮤추얼 펀드는 FUND, 콜론, 티커 순서입니다(FUND:VFIAX). SPY처럼 티커만 보내는 경우에도 미국 종목 하나를 가리키면 사용할 수 있으며, 응답에는 표준 id가 담깁니다.

응답 필드

필드유형전송의미
id문자열항상정식 종목 ID.
symbol문자열항상해당 거래소의 티커.
currency문자열항상모든 가격 필드의 통화. 펜스는 파운드로 환산됩니다.
price문자열선택currency 기준의 최종 가격.
previous_close문자열선택직전 거래일 종가. 알 수 없으면 제외됩니다.
change문자열선택price에서 previous_close를 뺀 값. previous_close가 제외되면 함께 제외됩니다.
change_percent문자열선택previous_close 대비 변동, 퍼센트 단위(1.5는 1.5%를 의미).
volume문자열선택오늘 거래된 주식 수. 알 수 없으면 제외되며, 지연 응답에서는 항상 제외됩니다.
market_session다음 중 하나: pre, open, post, closed선택timestamp 시점의 종목 거래소 상태: pre, open, post, closed 중 하나. pre와 post는 미국 거래소에만 있습니다.
timestamp날짜·시간선택가격이 유효했던 시각(UTC, 초 단위).
stale불리언항상거래소가 열려 있는 동안 가격이 15분보다 오래되었거나 갱신하지 못한 경우 true입니다. 휴장 중인 시장은 지연으로 처리되지 않습니다.
delayed항상 true선택전송되지 않음: 모든 계정에서 가격은 실시간입니다.
typeetf, mutual_fund 중 하나항상ETF는 etf, 뮤추얼 펀드는 mutual_fund입니다.
nav문자열선택currency 단위의 주당 순자산가치입니다.
previous_nav문자열선택전일 NAV입니다. 알 수 없으면 생략됩니다.
date날짜선택NAV의 기준일입니다(YYYY-MM-DD).
요청
curl -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/funds/ARCX:SPY/price"
응답 예시
{
  "id": "ARCX:SPY",
  "symbol": "SPY",
  "currency": "USD",
  "price": "578.12",
  "previous_close": "576.40",
  "change": "1.72",
  "change_percent": "0.30",
  "volume": "61230500",
  "market_session": "open",
  "timestamp": "2026-10-26T15:42:00Z",
  "stale": false,
  "type": "etf"
}

최대 50개 펀드의 최신 가격

GET /v1/funds/prices

나열된 각 펀드의 최신 가격으로, ETF는 최종 가격, 뮤추얼 펀드는 최신 NAV입니다. 가격이 반환된 id마다 호출 1회로 계산하며 한 번에 차감합니다. 조회에 성공한 id의 비용을 잔액으로 감당할 수 없으면 요청 전체가 402 insufficient_credits로 거부됩니다. 가격이 반환되지 않은 id는 errors에 나열되며 비용이 들지 않습니다. change_percent는 퍼센트 단위입니다.

ETF와 뮤추얼 펀드를 섞어 최대 50개의 id를 보낼 수 있습니다. 배치는 한 번에 차감됩니다. 조회에 성공한 id의 비용을 잔액으로 감당할 수 없으면 요청 전체가 402 insufficient_credits를 반환합니다.

MCP: 도구 funds, action prices.

매개변수

매개변수위치필수유형의미
ids쿼리예문자열쉼표로 구분한 펀드 id이며 중복을 제거한 뒤 최대 50개입니다. 각 id는 단건 가격 경로와 같은 규칙을 따릅니다. 가격이 반환된 id마다 호출 1회로 계산됩니다.

응답 필드

필드유형전송의미
prices객체 목록항상확인된 ID별 시세 하나씩.
prices[].id문자열항상정식 종목 ID.
prices[].symbol문자열항상해당 거래소의 티커.
prices[].currency문자열항상모든 가격 필드의 통화. 펜스는 파운드로 환산됩니다.
prices[].price문자열선택currency 기준의 최종 가격.
prices[].previous_close문자열선택직전 거래일 종가. 알 수 없으면 제외됩니다.
prices[].change문자열선택price에서 previous_close를 뺀 값. previous_close가 제외되면 함께 제외됩니다.
prices[].change_percent문자열선택previous_close 대비 변동, 퍼센트 단위(1.5는 1.5%를 의미).
prices[].volume문자열선택오늘 거래된 주식 수. 알 수 없으면 제외되며, 지연 응답에서는 항상 제외됩니다.
prices[].market_session다음 중 하나: pre, open, post, closed선택timestamp 시점의 종목 거래소 상태: pre, open, post, closed 중 하나. pre와 post는 미국 거래소에만 있습니다.
prices[].timestamp날짜·시간선택가격이 유효했던 시각(UTC, 초 단위).
prices[].stale불리언항상거래소가 열려 있는 동안 가격이 15분보다 오래되었거나 갱신하지 못한 경우 true입니다. 휴장 중인 시장은 지연으로 처리되지 않습니다.
prices[].delayed항상 true선택전송되지 않음: 모든 계정에서 가격은 실시간입니다.
prices[].typeetf, mutual_fund 중 하나항상ETF는 etf, 뮤추얼 펀드는 mutual_fund입니다.
prices[].nav문자열선택currency 단위의 주당 순자산가치입니다.
prices[].previous_nav문자열선택전일 NAV입니다. 알 수 없으면 생략됩니다.
prices[].date날짜선택NAV의 기준일입니다(YYYY-MM-DD).
errors객체 목록항상시세를 반환하지 않은 ID. 과금되지 않습니다.
errors[].id문자열항상요청한 그대로의 ID.
errors[].code다음 중 하나: not_found, not_covered, upstream_busy항상not_found: 해당 종목 없음. not_covered: 해당 거래소는 아직 시세가 없음. upstream_busy: 지금은 시세를 가져올 수 없으므로 잠시 후 다시 시도하십시오.
요청
curl -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/funds/prices?ids=ARCX:SPY,FUND:VFIAX"
응답 예시
{
  "prices": [
    {
      "id": "ARCX:SPY",
      "symbol": "SPY",
      "currency": "USD",
      "price": "578.12",
      "previous_close": "576.40",
      "change": "1.72",
      "change_percent": "0.30",
      "volume": "61230500",
      "market_session": "open",
      "timestamp": "2026-10-26T15:42:00Z",
      "stale": false,
      "type": "etf"
    },
    {
      "id": "FUND:VFIAX",
      "symbol": "VFIAX",
      "currency": "USD",
      "type": "mutual_fund",
      "nav": "551.07",
      "previous_nav": "549.80",
      "change": "1.27",
      "change_percent": "0.23",
      "date": "2026-10-23",
      "stale": false
    }
  ],
  "errors": [
    {
      "id": "FUND:NOPE",
      "code": "not_found"
    }
  ]
}

펀드 하나의 가격 봉

GET /v1/funds/{id}/bars

일봉(1d) 또는 1분봉(1m)을 오래된 순으로 주식 봉 형식으로 반환합니다. 뮤추얼 펀드의 일봉은 일별 NAV입니다(시가, 고가, 저가, 종가가 모두 NAV이며 거래량은 없습니다). 뮤추얼 펀드에는 1분봉이 없습니다(400 invalid_interval). 1분봉은 ETF만 해당합니다. 이력은 모든 계정에 전체 기간이 제공됩니다. 한 페이지에 최대 5,000개의 봉이 담기며 next_cursor가 함께 반환됩니다. 가격과 더 이상 맞지 않는 커서는 409 cursor_expired입니다. 페이지당 호출 1회입니다.

두 페이지 사이에 분할이나 분배금으로 이력이 바뀌면 커서가 더 이상 동작하지 않고 409 cursor_expired가 반환됩니다.

MCP: 도구 funds, action bars.

매개변수

매개변수위치필수유형의미
id경로예문자열펀드 id입니다. ETF는 종목 id로, 거래소의 네 글자 코드, 콜론, 티커 순서입니다(ARCX:SPY). 뮤추얼 펀드는 FUND, 콜론, 티커 순서입니다(FUND:VFIAX). SPY처럼 티커만 보내는 경우에도 미국 종목 하나를 가리키면 사용할 수 있으며, 응답에는 표준 id가 담깁니다.
interval쿼리아니요다음 중 하나: 1d, 1m1d(거래일당 봉 1개이며 뮤추얼 펀드의 봉은 일별 NAV) 또는 1m(1분봉이며 ETF만 해당). 그 외의 값은 400 invalid_interval입니다.
start쿼리아니요문자열첫 봉. 1d: 날짜(YYYY-MM-DD), 해당 일 포함, 생략하면 가장 오래된 봉. 1m: UTC 시각(YYYY-MM-DDTHH:MM:SSZ, 또는 00:00 UTC를 뜻하는 날짜), 포함, 생략하면 end의 하루 전.
end쿼리아니요문자열마지막 봉. 1d: 날짜, 해당 일 포함, 생략하면 봉이 나온 가장 최근 세션. 1m: UTC 시각, 해당 시각 미포함, 생략하면 현재 또는 start로부터 5일 뒤. 1m에서 start와 end 사이는 최대 5일입니다(400 range_too_large).
cursor쿼리아니요문자열이전 페이지의 next_cursor. 다른 매개변수는 동일하게 유지합니다. 커서 뒤의 가격이 바뀌면(분할 또는 배당) 커서가 작동하지 않으며 409 cursor_expired입니다.

응답 필드

필드유형전송의미
id문자열항상정식 종목 ID.
currency문자열항상모든 가격의 통화. 펜스는 파운드가 됩니다.
adjusted불리언항상항상 true: 가격은 분할과 배당이 반영되어 조정됩니다. 한 페이지와 다음 페이지는 항상 일치하며, 두 페이지 사이에 분할이나 배당으로 이력이 바뀌면 둘을 섞지 않고 커서가 작동하지 않습니다(409 cursor_expired).
start문자열선택전송되지 않음: start는 이동되지 않습니다.
end문자열선택전송되지 않음: 일봉은 잘리지 않습니다.
bars객체 목록항상한 페이지에 최대 5,000개의 봉.
bars[].date문자열선택세션 날짜(YYYY-MM-DD). 일봉에만 있으며 1분봉에서는 제외됩니다.
bars[].timestamp날짜·시간항상봉 기간의 시작(UTC): 일봉은 거래소 개장 시각, 1분봉은 해당 분.
bars[].open문자열항상해당 기간의 첫 가격입니다.
bars[].high문자열항상해당 기간의 최고가입니다.
bars[].low문자열항상해당 기간의 최저가입니다.
bars[].close문자열항상해당 기간의 마지막 가격입니다.
bars[].volume문자열선택기간 중 거래된 주식 수. 알 수 없으면 제외됩니다.
next_cursor문자열항상다음 페이지를 읽으려면 이 값을 다시 전달합니다. 마지막 페이지에서는 null입니다.
요청
curl -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/funds/ARCX:SPY/bars?interval=1d&start=2026-10-01"
응답 예시
{
  "id": "ARCX:SPY",
  "currency": "USD",
  "adjusted": true,
  "bars": [
    {
      "date": "2026-10-23",
      "timestamp": "2026-10-23T13:30:00Z",
      "open": "575.10",
      "high": "577.60",
      "low": "573.90",
      "close": "576.40",
      "volume": "48210300"
    }
  ],
  "next_cursor": null
}

펀드 하나의 분배금

GET /v1/funds/{id}/distributions

펀드 하나의 분배금을 권리락일이 최근인 순으로 페이지 단위로 반환합니다. 모든 계정에 전체 이력이 제공됩니다. 요청마다 호출 1회로 계산됩니다. 알 수 없는 id는 404 not_found입니다.

MCP: 도구 funds, action distributions.

매개변수

매개변수위치필수유형의미
id경로예문자열펀드 id입니다. ETF는 종목 id로, 거래소의 네 글자 코드, 콜론, 티커 순서입니다(ARCX:SPY). 뮤추얼 펀드는 FUND, 콜론, 티커 순서입니다(FUND:VFIAX). SPY처럼 티커만 보내는 경우에도 미국 종목 하나를 가리키면 사용할 수 있으며, 응답에는 표준 id가 담깁니다.
cursor쿼리아니요문자열이전 페이지의 next_cursor. 다른 매개변수는 동일하게 유지합니다.

응답 필드

필드유형전송의미
id문자열항상표준 펀드 id입니다.
start날짜선택전송되지 않음: 모든 계정에 전체 이력을 제공합니다.
distributions객체 목록항상권리락일이 최근인 순입니다.
distributions[].ex_date날짜항상펀드가 분배금 없이 거래되는 첫날입니다.
distributions[].amount문자열항상currency 단위의 주당 분배금입니다.
distributions[].currency문자열항상amount의 통화입니다.
distributions[].pay_date날짜선택지급일. 알 수 없으면 제외됩니다.
distributions[].record_date날짜선택주주가 명부에 올라 있어야 하는 날(기준일). 알 수 없으면 제외됩니다.
distributions[].kindincome, capital_gain 중 하나선택분배금의 종류입니다. 출처에서 알려 주지 않으면 생략됩니다.
next_cursor문자열항상다음 페이지를 읽으려면 cursor로 전달합니다. 마지막 페이지에서는 null입니다.
요청
curl -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/funds/ARCX:SPY/distributions"
응답 예시
{
  "id": "ARCX:SPY",
  "distributions": [
    {
      "ex_date": "2026-09-18",
      "amount": "1.78",
      "currency": "USD",
      "pay_date": "2026-10-30",
      "record_date": "2026-09-18"
    }
  ],
  "next_cursor": null
}

오류

오류는 공통 문제 형식을 사용하며, 다음 필드를 포함합니다: request_id. 확인 API 오류 코드와 크레딧 형식과 크레딧 헤더에 대한 설명이 있습니다. 실패한 요청에는 요금이 부과되지 않습니다.

코드상태의미
invalid_query400매개변수가 없거나, 알 수 없거나, 중복되었거나, 범위를 벗어났습니다.
invalid_id400id 또는 페어가 이 API에서 요구하는 형식과 다릅니다.
too_many_ids400배치에 50개를 넘는 id가 들어 있습니다.
invalid_interval400interval이 1d 또는 1m이 아니거나, 이 상품에서는 사용할 수 없습니다.
range_too_large400기간이 이 경로에서 허용하는 길이를 넘었습니다.
not_found404해당하는 종목, 펀드 또는 페어가 없습니다.
invalid_cursor400이 요청이 반환한 커서가 아니거나, 다른 요청의 커서입니다.
cursor_expired409커서가 가리키는 가격이 바뀌었습니다. 커서 없이 처음부터 다시 요청하십시오.
insufficient_credits402크레딧 잔액이 요청 비용보다 적습니다.
upstream_busy503지금은 가격을 가져올 수 없습니다. 배치에서는 errors에 나열됩니다. 잠시 후 다시 시도하십시오.
area_unavailable503이 영역은 지금 응답할 수 없습니다.

이 페이지가 도움이 되었나요?