← 전체 글로

AI 사용기

AI 활용기: 100건까지만 응답하는 API를 4단계 끝나서야 알았다

공개 API가 상한선을 조용히 넘기며 데이터를 잘라주는 문제를, 앱 기획 4단계를 다 마친 뒤에야 발견한 사례와 같은 함정을 다룬 해외 기술 글을 같이 정리했다.

이 글의 목적

외부 API를 근거로 앱이나 콘텐츠를 기획하는 사람에게, '문서를 읽었다'와 '실제로 호출해봤다'가 왜 다른 확인인지 구체적 사례로 보여준다.

핵심 내용

찬송가 앱 기획에서 '같은 찬송이 몇 개 찬송가에 실렸는가'를 핵심 지표로 잡고 1~4단계(기획·경쟁조사·사양·디자인)를 전부 끝냈는데, 5단계 구현 직전 실제 API를 호출해보니 정확히 100건인 응답만 있고 95~99건은 하나도 없었다 — 상한이 100이라 실제로는 '100건 이상'인데 '100건'으로 잘려 있었다. Notion API의 1만 건 페이지네이션 상한, PI Web API의 '요청한 개수와 정확히 같으면 잘린 것' 이라는 업계 조언과 같은 종류의 함정이었다.

읽고 나서

외부 API를 근거로 지표를 설계할 때는 문서를 읽는 대신 실제로 몇 번 호출해 응답 분포를 눈으로 확인하고, 반환된 개수가 요청한 상한과 정확히 같은 경우가 있는지부터 센다.

목차

먼저 답하면

API 응답이 정확히 요청 상한과 같은 개수로 돌아오는 경우가 있다면, 그건 ’딱 그만큼 있다’가 아니라 ’그 이상인데 잘렸다’로 의심해야 한다. 문서에는 이 상한이 안 적혀 있을 수 있다.

4단계까지 초록, 5단계 직전에 뒤집힌 축

찬송가 관련 앱을 기획하면서 “같은 찬송이 여러 찬송가 판본에 몇 번 실렸는가”를 화면의 핵심 숫자로 잡았다. 기획·경쟁조사·사양·디자인 네 단계를 전부 이 축으로 끝냈다. 문제는 그다음이었다. 실제 구현 직전에 참고할 공개 API(Hymnary.org)를 직접 호출해보니, 그 API는 첫 행·제목·운율·작사자 생몰년·수록 찬송가 수·인용 성경 장절은 주지만 판본별 번호는 아예 주지 않았다. 화면에 “305번”이라고 적으려면 그 숫자의 근거가 나 혼자뿐이 되는 셈이었고, 그건 “사실만 싣는다”는 그 앱의 전제 자체를 깨는 문제였다.

축을 다시 잡으면서 같은 조사에서 발견한 함정이 세 가지 더 있었다.

  1. 응답이 조용히 잘렸다. 정확히 100건인 장(章)이 30개인데, 95~99건인 장은 하나도 없었다. 즉 100은 “딱 100”이 아니라 “100 이상인데 100에서 끊긴” 결과였다. 상한을 넘긴 응답은 에러를 던지지 않고 그냥 200으로 돌아왔다.
  2. 출처가 “미상”을 이름처럼 돌려줬다. author: "Anonymous"를 그대로 화면에 실으면 사람 이름처럼 보인다. 실제로는 “작사자 불명”이라는 사실이므로 값을 비운 뒤 화면이 그 언어로 “미상”이라 말하게 고쳐야 했다.
  3. 표준 약어를 못 읽으면 데이터가 통째로 빠졌다. 운율 표기 C.M.·L.M.·S.M. 380건을 그냥 “미상”으로 버리고 있었는데, 그중에는 2,606개 찬송가에 실린 곡도 섞여 있었다.

세 함정 모두 “문서에 써 있는 필드 이름”과 “실제로 받은 값”을 대조하지 않으면 못 잡는 종류였다. 다행히 아직 코드를 짜기 전이라 되돌릴 게 계획 문서뿐이었지, 한 단계만 늦었어도 이미 만든 화면과 목업을 통째로 버려야 했을 것이다.

같은 함정을 다룬 해외 사례

이 truncation(잘림) 문제는 흔한 유형이다. 2026년 초 Notion API는 페이지네이션 조회에 1만 건 상한을 뒀는데, 이 한도를 넘긴 응답은 여전히 200 OK로 오고 next_cursor만 비어 있다. dev.to에 정리된 사례를 보면, 실제로 이 한도를 몰랐던 동기화 스크립트들은 몇 주 동안 조용히 데이터를 빠뜨리다가 “이 항목이 왜 리포트에 없냐”는 사람의 신고를 받고서야 발견됐다고 한다. 특히 마이그레이션처럼 “한 번 돌리고 끝”인 작업은 잘린 채로 성공한 것처럼 보이고, 원본을 이미 정리한 뒤에야 빠진 데이터를 알아채는 경우가 많다고 지적한다.

산업용 데이터 API인 PI Web API 쪽 정리 글도 같은 결론을 낸다. PiSharp의 설명에 따르면 이 API는 잘렸다는 신호(헤더나 플래그)를 아예 주지 않기 때문에, maxCount=1000을 요청해서 정확히 1,000건이 돌아왔다면 잘렸다고 의심하는 게 기본 습관이어야 한다고 조언한다. 내가 겪은 “정확히 100건만 있고 95~99건이 없다”는 관찰과 원리가 같다.

이 문제를 예방하는 방법론도 이미 이름이 있다. Pragmatic Programmer가 제안한 “tracer bullet(추적 사격)” 내지 “walking skeleton” 접근은, 기능을 문서로 설계하기 전에 가장 위험한 외부 의존성부터 실제로 한 번 끝까지 통과시켜보라고 말한다. 이 개념을 정리한 글은 “제3자 서비스나 타 조직 의존성이 있는 부분이 가장 위험하니, 그 부분부터 공을 굴려봐야 한다”고 설명한다. 목적은 완성된 기능을 내놓는 게 아니라, 실제로 호출해보며 배우는 것이다.

문서를 읽는 것과 응답을 받아보는 것은 다른 확인이다

세 사례를 나란히 놓으면 공통점이 뚜렷하다. 문서는 상한을 안 알려주거나(Hymnary.org, PI Web API), 알려줘도 실제 동작을 다 설명하지 않는다(Notion). 확인하는 방법은 결국 하나, 그 API를 실제로 여러 번 불러서 응답의 분포를 눈으로 보는 것이다. 반환된 개수가 요청한 상한과 정확히 같은 케이스가 있는지, 특정 범위의 값이 부자연스럽게 하나도 없는 구간이 있는지를 세어보면 잘림은 대체로 드러난다.

이후로는 외부 API를 지표의 근거로 쓰기로 정하기 전에, 기획 문서를 쓰기보다 먼저 그 API를 몇 번 호출해 원응답을 저장해두는 순서로 바꿨다. 사양의 필드 표도 그 원응답에 있는 필드로만 채우고, 응답에 없는 값은 아무리 필요해 보여도 손으로 채워 넣지 않는다.