공공데이터포털(data.go.kr)에는 정말 많은 API가 있습니다.
그중에서도 조달청이 제공하는 나라장터 입찰공고정보서비스는 개인 개발자에게도 무료로 개방돼 있습니다.
저희가 이 API를 어떻게 활용해 실시간 알림 서비스를 만들었는지 간단히 공유합니다.
어떤 API인가요
서비스 ID는 15129394이고, 25개 오퍼레이션으로 구성돼 있습니다.
물품·용역·공사·외자 업무 구분마다 별도 오퍼레이션이 있어서, 한 번의 크론 실행에서 4개 API를 호출해야 전체 공고를 커버할 수 있습니다.
JSON과 XML 두 가지 형식을 지원하고, 초당 30 TPS까지 허용됩니다.
2025년 2월부터 24시간 개방으로 전환됐습니다.
어떤 데이터가 들어오나요
주요 필드만 정리하면 이렇습니다.
공고번호, 공고명, 공고기관, 수요기관, 계약체결방법, 낙찰자결정방법, 배정예산, 추정가격, 개찰일시, 마감일시, 참가가능지역, 참가가능업종 등.
이 중 공고명은 최대 1,000자까지 지원되고, 실제로 긴 공고명이 자주 등장합니다.
필드가 나오는 형식은 서비스마다 조금씩 다릅니다.
개방표준서비스와 입찰공고정보서비스에서 같은 개념을 다른 이름으로 부르기도 합니다.
예를 들어 수요기관코드는 개방표준에선 dmndInsttCd, 입찰공고정보에선 dminsttCd로 나옵니다.
매핑 로직을 잘 정리해 두는 게 실무에서 중요합니다.
저희 파이프라인 구조
5분 주기 크론이 돌면서 다음 순서로 동작합니다.
API 호출 → JSONL 파일 저장 → MariaDB로 인제스트 → 사용자 키워드와 매칭 → 발송 큐에 등록 → 텔레그램/카카오/이메일 발송.
스펙 변경이 잦아서 원본 JSON을 raw_json 컬럼에 통째로 보관해 뒀습니다.
새 필드가 추가되면 파서만 갱신하면 되니까 안정적입니다.
실전 함정 몇 가지
ServiceKey는 반드시 URL 인코딩된 형태로 사용해야 합니다.
그렇지 않으면 SERVICE_KEY_IS_NOT_REGISTERED_ERROR가 뜹니다.
개발계정은 하루 1,000건 제한이라 5분 폴링만 해도 금방 초과합니다.
운영계정으로 승격이 필수입니다.
또 하나, 낙찰정보서비스는 조회 기간이 1일로 축소됐습니다(2026-06 변경).
백필 시 날짜를 자동 분할하는 로직이 필요합니다.
저희는 15일 단위로 나눠서 호출하도록 구현해 뒀습니다.
결론
공공데이터 API는 처음 진입할 때는 문서가 복잡해 보이지만, 한번 파이프라인을 구축해 두면 안정적으로 흘러갑니다.
직접 만들지 않고 저희 서비스를 쓰시는 것도 좋은 선택이지만, 관심 있으시면 조달청 활용가이드 문서를 한 번쯤 훑어보시길 권합니다.
데이터의 힘은 결국 활용하는 사람 손에 달렸으니까요.