공공데이터 API 처음 쓰기, 계란 가격 가져오기
공공데이터포털에서 인증키를 발급받아 파이썬으로 계란 시세를 받아오는 과정을 처음 해 보는 사람 기준으로 정리했습니다. 인코딩 키 함정과 에러 코드 읽는 법까지 담았습니다.

낮에는 회사에서 일하고, 밤에는 코드를 만지고, 주말에는 부엌에 있습니다. 겪은 것을 정리해 두는 곳입니다.
목차
공공데이터 API는 회원가입, 활용신청, 인증키 복사, 파이썬 다섯 줄이면 첫 데이터가 나옵니다. 코드보다 먼저 막히는 건 대부분 인증키입니다. 포털이 인증키를 두 종류로 주는데, 둘 중 아무거나 쓰면 오류가 나기 때문입니다. 이 글은 API를 한 번도 써 본 적 없는 분이 계란 시세를 받아오는 데까지 그대로 따라올 수 있게 쓴 기록입니다.
저는 계란 회사에서 일하면서 사내 시스템을 만들고 있습니다. 계란 시세, 공휴일, 거래처 사업자등록 폐업 여부 같은 데이터를 공공데이터포털에서 받아다 쓰고 있는데, 세 가지 모두 무료입니다 .
한 줄 요약 인증키는 두 종류입니다. 파이썬 코드에서는 보통 디코딩 키를 씁니다.
공공데이터 API가 뭔가요
공공데이터 API는 정부 기관이 가진 자료를 프로그램이 직접 받아 갈 수 있게 열어 둔 통로입니다. 사람이 홈페이지에 들어가 표를 보는 대신, 프로그램이 주소를 하나 요청하면 자료를 글자 뭉치로 돌려줍니다.
API라는 말이 낯설다면 식당 주문을 떠올리면 이해가 빠릅니다. 주방에 직접 들어가는 대신 메뉴판을 보고 점원에게 주문하면 음식이 나오죠. API는 그 메뉴판이자 점원입니다. 무엇을 달라고 말할 수 있는지 정해 놓고, 정해진 형식으로 물어보면 정해진 형식으로 답을 줍니다.
우리나라 공공데이터는 대부분 공공데이터포털(data.go.kr) 한 곳에 모여 있습니다. 부처와 기관이 제각각 열어 둔 API를 한 자리에서 신청하고 관리할 수 있습니다. 대부분 무료이고, 인증키 하나로 여러 API를 쓸 수 있습니다.

인증키는 어떻게 발급받나
공공데이터포털에 회원가입한 뒤, 쓰려는 API 페이지에서 "활용신청" 버튼을 누르면 인증키가 나옵니다. 대부분 자동승인이라 신청하자마자 쓸 수 있습니다.
인증키란 이 요청을 누가 보냈는지 알려 주는 긴 문자열입니다. 도서관 회원증과 비슷합니다. 책은 누구나 빌릴 수 있지만 회원증은 있어야 하고, 하루에 몇 권까지 빌릴 수 있는지도 회원증으로 관리되죠. 인증키가 없으면 서버가 요청을 거절합니다.
data.go.kr에 접속해 회원가입하고 로그인합니다.
상단 검색창에 쓰려는 데이터 이름을 넣고 검색합니다.
검색 결과에서 "오픈 API" 쪽에 있는 항목을 고릅니다. "파일데이터"는 엑셀 파일을 내려받는 것이라 다릅니다.
오른쪽 위 "활용신청"을 누르고, 활용 목적을 고른 뒤 신청합니다.
마이페이지의 "개발계정" 목록에 방금 신청한 API가 보이면 신청이 끝난 것입니다.
여기서 자주 헷갈리는 두 가지가 있습니다. 하나는 개발계정과 운영계정입니다. 처음 신청하면 개발계정이 되고, 하루 호출 한도가 1,000건 정도로 제한됩니다. 혼자 쓸 정도라면 이걸로 충분합니다. 실제 서비스에 넣을 만큼 많이 부르게 되면 그때 운영계정으로 신청을 올리면 됩니다.
다른 하나는 활용신청이 API마다 따로라는 점입니다. 회원가입 한 번으로 모든 데이터가 열리지 않습니다. 새 데이터를 쓸 때마다 그 페이지에서 다시 활용신청을 눌러야 합니다.
인코딩 키와 디코딩 키, 여기서 제일 많이 막힙니다
마이페이지에 가면 인증키가 일반 인증키(Encoding)와 일반 인증키(Decoding) 두 줄로 보입니다. 둘은 같은 키인데 표기 방식만 다릅니다. 인코딩 키는 특수문자가 %2F, %3D 같은 기호로 바뀌어 있고, 디코딩 키는 /나 =가 그대로 들어 있습니다.
파이썬 requests로 부를 때는 보통 디코딩 키를 씁니다. 왜냐하면 requests가 주소를 만들면서 특수문자를 알아서 변환해 주기 때문입니다. 여기에 이미 변환된 인코딩 키를 넣으면 변환이 두 번 일어나서, 서버 입장에서는 전혀 다른 키가 됩니다.
반대로 브라우저 주소창에 주소를 통째로 붙여 넣어 시험해 볼 때는 인코딩 키를 씁니다. 이때는 변환해 주는 사람이 없으니까요.
인증키를 제대로 넣었는데도 계속 오류가 난다면, 다른 쪽 키로 한 번 바꿔서 넣어 보세요. 저도 처음에 이걸로 한참 헤맸습니다.
그리고 인증키는 비밀번호와 같습니다. 블로그나 깃허브에 코드를 올릴 때 키가 그대로 들어가지 않게 주의해야 합니다. 남이 내 키로 호출하면 내 한도가 소진됩니다.
계란 가격은 어떤 API를 신청하나
계란 시세는 축산물품질평가원_가금산물 일일거래가격정보에서 받습니다. 포털 검색창에 "가금산물 일일거래가격"이라고 치면 나옵니다. 육계, 계란, 오리의 하루 거래가격을 다음 날 정리해서 올려 주는 자료입니다. 무료이고 자동승인이며, 데이터는 XML 형식으로 옵니다.
이 API는 하나의 신청 안에 여러 기능이 들어 있습니다. 페이지 아래쪽 "활용 정보 → 상세기능"에 있는 드롭다운을 열면 토종닭 가격조회, 산란계(노계) 가격조회, 육계(산지) 일일가격조회, 계란 일일가격조회 같은 목록이 보입니다. 여기서 계란 일일가격조회를 고르면 그 기능의 요청 주소와 넣어야 할 값이 화면에 표시됩니다.
주소는 기능마다 끝부분이 다릅니다. 예를 들어 토종닭 가격조회는 이렇게 생겼습니다.
http://data.ekape.or.kr/openapi-data/service/user/grade/poultry/nativechichen
계란 일일가격조회의 주소는 같은 화면에서 그대로 복사해 쓰시면 됩니다. 화면에 적힌 값을 그대로 쓰는 게 중요합니다. 기관이 주소를 바꾸는 일이 가끔 있어서, 남의 블로그에 적힌 주소보다 포털 화면이 항상 최신입니다.
넣어야 하는 값은 대체로 다섯 가지입니다. 인증키(serviceKey), 페이지 번호(pageNo), 한 페이지에 몇 개를 받을지(numOfRows), 조회 시작일(startYmd), 조회 종료일(endYmd)입니다. 날짜는 20260913처럼 하이픈 없이 여덟 자리로 씁니다.
파이썬으로 첫 호출 해 보기
파이썬에서는 requests라는 도구로 API를 부릅니다. 터미널에 아래 명령을 넣어 설치합니다. 인터넷으로 자료를 요청하고 받아 오는 일을 대신해 주는 도구입니다.
pip install requests그다음 아래 코드를 egg.py 같은 이름으로 저장하고 실행합니다. 이 코드는 서버에 계란 가격을 요청하고, 돌아온 답을 화면에 그대로 찍어 봅니다.
import requestsURL = "여기에_상세기능_화면의_서비스_URL을_붙여넣기"KEY = "여기에_디코딩_인증키를_붙여넣기"params = { "serviceKey": KEY, "pageNo": 1, "numOfRows": 10, "startYmd": "20260901", "endYmd": "20260913",}res = requests.get(URL, params=params, timeout=10)print(res.status_code) # 200이면 서버까지는 잘 갔다는 뜻print(res.text[:800]) # 돌아온 내용의 앞부분만 확인처음부터 자료를 예쁘게 정리하려 하지 말고, 일단 눈으로 확인하는 단계를 꼭 거치는 게 좋습니다. 왜냐하면 API마다 돌려주는 모양이 조금씩 달라서, 실제 응답을 보기 전에는 어떤 이름으로 값이 들어오는지 알 수 없기 때문입니다.
200이 찍히고 <resultCode>00</resultCode>이나 OK 같은 글자가 보이면 성공입니다. 그런데 여기서 한 가지 주의할 게 있습니다. 오류가 나도 status_code는 200으로 나옵니다. 통로 자체는 정상이고 내용물만 오류라는 뜻이라, 숫자 200만 보고 성공했다고 판단하면 안 됩니다. 반드시 res.text 안쪽을 봐야 합니다.
XML로 온 자료에서 값만 뽑으려면 파이썬에 기본으로 들어 있는 도구를 씁니다. 아래는 응답 안에 있는 항목들을 하나씩 꺼내 보는 코드입니다.
import xml.etree.ElementTree as ETroot = ET.fromstring(res.text)for item in root.iter("item"): for child in item: print(child.tag, child.text) # 항목 이름과 값을 나란히 출력child.tag가 항목 이름, child.text가 실제 값입니다. 어떤 이름으로 가격이 들어오는지 여기서 확인한 뒤에, 필요한 항목만 골라 쓰면 됩니다.
에러 메시지는 이렇게 읽습니다
공공데이터포털은 오류를 코드와 영어 문장으로 알려 줍니다. 처음 보면 당황스럽지만 종류가 많지 않습니다. 제가 자주 만난 것들입니다.
SERVICE_KEY_IS_NOT_REGISTERED_ERROR(30): 등록되지 않은 인증키입니다. 인코딩 키와 디코딩 키를 바꿔 넣어 보고, 그 API에 활용신청을 했는지 확인합니다. 신청 직후라면 반영에 시간이 조금 걸릴 수 있으니 잠시 뒤 다시 호출해 봅니다.SERVICE_ACCESS_DENIED_ERROR(20): 키는 맞는데 이 API를 쓸 권한이 없습니다. 다른 API 인증키를 가져다 쓴 경우가 많습니다.INVALID_REQUEST_PARAMETER_ERROR(10): 넣은 값의 형식이 틀렸습니다. 날짜에 하이픈이 들어갔거나, 필수 항목을 빼먹은 경우입니다.LIMITED_NUMBER_OF_SERVICE_REQUESTS_EXCEEDS_ERROR(22): 하루 호출 한도를 넘겼습니다. 다음 날까지 기다리거나 운영계정을 신청합니다.NO_OPENAPI_SERVICE_ERROR(12): 주소에 오타가 있거나 그 서비스가 없어졌습니다.
오류가 났을 때 코드를 뜯어고치기 전에 응답 내용을 먼저 통째로 읽어 보세요. 대부분 서버가 무엇이 잘못됐는지 이미 알려 주고 있습니다.
공휴일 데이터로 배송 일정 계산하기
공휴일은 한국천문연구원의 특일 정보 API로 받습니다. 연도와 월을 넣으면 그달의 공휴일 날짜와 이름이 돌아옵니다.
URL = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo"params = { "serviceKey": KEY, "solYear": "2026", # 연도 "solMonth": "09", # 월, 두 자리로 "numOfRows": 30, # 한 달에 공휴일이 10개를 넘는 달이 있어서 넉넉히}res = requests.get(URL, params=params, timeout=10)돌아오는 값에서 locdate가 날짜(20260925 형식), dateName이 이름(추석 등), isHoliday가 쉬는 날인지 여부입니다.
numOfRows를 넉넉히 넣는 이유가 있습니다. 이 값을 적어 두면 첫 페이지에 그만큼만 나오고 나머지는 잘려 버립니다. 연휴가 겹치는 달에 공휴일 하나가 빠지면, 그걸로 계산한 배송 일정이 통째로 어긋납니다.
저는 이 데이터를 발주 마감일 계산에 씁니다. 계란은 신선식품이라 연휴 앞뒤 며칠이 특히 중요합니다 .
거래처 폐업 여부 확인하기
거래처가 폐업했는지는 국세청의 사업자등록정보 진위확인 및 상태조회 서비스로 확인합니다. 사업자등록번호만 넣으면 계속사업자인지, 휴업인지, 폐업인지와 폐업일자까지 돌아옵니다. 한 번에 최대 100개까지 조회할 수 있습니다.
이 API는 앞의 두 개와 부르는 방식이 다릅니다. 주소에 값을 붙이는 GET이 아니라, 내용을 따로 담아 보내는 POST 방식입니다. 조회할 사업자번호가 100개까지 들어갈 수 있어서, 주소 뒤에 다 붙이기 어렵기 때문입니다.
URL = "https://api.odcloud.kr/api/nts-businessman/v1/status"res = requests.post( URL, params={"serviceKey": KEY}, json={"b_no": ["0000000000", "1111111111"]}, # 하이픈 없이 열 자리 timeout=10,)print(res.json()["data"])응답의 b_stt에 계속사업자, 휴업자, 폐업자 중 하나가 들어옵니다. tax_type은 과세 유형, end_dt는 폐업일자입니다. 이 API는 JSON 형식이라 앞의 XML 파싱 없이 res.json()으로 바로 꺼낼 수 있습니다.
한 가지 알아 두면 좋은 게 있습니다. 이 데이터는 국세청 정보와 30분 주기로 맞춰지고, 새로 개업한 사업자는 반영에 하루 이틀 걸립니다. 그래서 방금 사업자등록을 낸 거래처가 조회되지 않는다고 해서 잘못된 번호는 아닙니다.
주의 거래처의 사업자등록번호는 남의 정보입니다. 조회한 결과를 어디에 저장하고 얼마나 보관할지는 미리 정해 두는 편이 좋습니다.
어렵다기보다 안내가 흩어져 있었습니다
돌아보면 코드가 어려웠던 적은 없었습니다. 막힌 건 전부 인증키나 활용신청처럼 코드 바깥의 절차였고, 그 설명이 여기저기 흩어져 있어서 시간이 걸렸습니다. 한 번 통과하고 나니 다른 API를 붙이는 데는 십 분이면 충분했습니다. 정부 기관이 이미 정리해 둔 자료가 생각보다 많다는 것도 이번에 알았습니다. 날씨, 방역, 여객선 결항까지 붙여 볼 생각입니다. 혹시 업무에 쓸 자료를 매번 손으로 옮겨 적고 계신다면, 그 자료가 공공데이터포털에 이미 열려 있는지 한 번 검색해 보시길 권하고 싶습니다.