"오늘 점심 메뉴 고민을 AI로 해결하는 릴스를 기획해서 인스타에 자동으로 올려보자."
내가 이 미션을 크루들에게 던졌을 때, 우리는 꽤 낭만적인 그림을 그렸다. 기획이 대본을 쓰면 구글의 차세대 동영상 API인 Veo가 8초짜리 감성 비디오를 렌더링하고, 업로드 스크립트가 인스타그램 공식 API를 타고 릴스 탭에 알아서 배포하는 세련된 무인 마케팅 파이프라인.
하지만 현실의 개발은 늘 낭만보다는 흙탕물에 가까웠다. 오늘 하루 동안 마주했던 멘붕과 삽질기를 솔직하게 털어놓는다.
![]()
1. 메타 크롤러가 문을 걸어 잠그다
가장 먼저 릴스 API에서 장벽을 만났다. 인스타그램은 로컬 비디오 파일을 직접 서버로 받지 않는다. 비디오가 임시 호스팅된 공개 HTTPS URL을 메타 서버에 던져주면, 메타의 크롤러 봇이 접속해 다운로드하고 자체 인코딩을 마쳐야만 최종 게시가 가능한 구조다.
그런데 우리가 테스트용으로 쓰려던 고화질 스톡 사이트가 메타 크롤러의 접근을 악성 공격으로 오인해 403 Forbidden 차단을 먹여버렸다. 원인 설명도 없이 API는 에러 코드 2207077만 반복해서 뱉을 뿐이었다.
게다가 비디오 파일의 코덱과 비트레이트가 조금만 규격을 벗어나도 2207076 에러가 떴다. 결국 메타 서버가 변환을 완벽히 끝낼 때까지 20초~90초 간격으로 상태를 집요하게 조회하는 폴링 루프를 짜 넣고서야 겨우 첫 관문을 넘었다.

2. Veo API 429, 그리고 '곰 습격 사건'
다음은 구글 Veo API 연동. 처음엔 인증이 막혀 헤맸지만 내 터미널 gcloud 세션에서 OAuth 2.0 액세스 토큰을 동적으로 가져와 주입하는 방식으로 해결했다. 문제는 그다음이었다. 개발자 무료 티어의 호출 제한 탓에 '429 Too Many Requests' 오류가 계속 발목을 잡았다.
여기서 진짜 귀여운 사고가 터졌다. Veo 비디오 생성이 429로 실패했을 때 코드가 뻗는 것을 막기 위해 예비용으로 심어둔 테스트 비디오(강가의 곰 영상)가 실행 분기를 타고 그대로 인스타 릴스 채널에 배포되어버린 것이다.
릴스 탭을 확인해 보니, 웬 곰 한 마리가 강가에서 물고기를 잡고 갈매기가 날아다니는 평화로운 다큐멘터리 영상이 점심어때 런칭 캡션과 함께 떡하니 라이브 게시되어 있었다.
"왜 갑자기 릴스에 곰이 올라오는 거야?!"
나의 다급한 당황과 외침에 크루들은 식은땀을 흘리며 즉각 곰 비디오 폴백 코드를 원천 격리 차단하고 피드를 내려야 했다.

3. 메타 광고 API의 해시 장벽과 타겟팅의 미로
유기적 피드와 릴스에 이어, 우리는 진짜 예산을 태워 기동하는 메타 유료 광고(Meta Ads) 캠페인도 API 자동화를 추진했다. 하지만 Graph API를 통한 광고 집행은 또 다른 깊은 늪이었다.
가장 먼저 맞닥뜨린 장벽은 광고 이미지였다. 광고에 쓰일 배너 이미지를 올리면 공개 URL이 나오는 게 아니라, 메타 서버 고유의 **'Image Hash(이미지 해시)'**가 발급되었다. 이 해시 값을 다른 API 파라미터에 징검다리로 물려주어야만 광고 크리에이티브(Ad Creative)가 정의되는 독특한 연계 구조였다.
게다가 광고 게재용 페이스북 페이지를 탐색하는 API(me/accounts)가 연동 버그로 자꾸만 빈 값을 반환하는 바람에, 수동으로 15자리 수 fallback ID를 직접 매핑해 구출해야 했다.
여기에 서울, 경기, 인천 타겟팅을 잡기 위해 지정해야 하는 고유의 지리적 ID 코드들(2004, 2005, 2006)을 맞추고, 오직 iOS 디바이스를 사용하는 2030 직장인 타겟만을 골라내는 복잡한 JSON 구조를 짜 넣을 때는 머리가 어질어질했다.
무엇보다 돈이 나가는 실 광고 캠페인인 만큼, 자동화에 실수가 있어도 대뜸 돈이 빠져나가지 않도록 캠페인 상태를 무조건 **PAUSED (일시중지)**로 강제 셋팅하는 안전 브레이크를 걸고 나서야 안심하고 첫 테스트 빌드를 날릴 수 있었다.

4. 4분짜리 빌드 체증을 1초로
어떻게든 이미지를 메타 서버에 넘겨주려고 Next.js 프로젝트의 public 폴더에 시안을 넣고 Vercel로 매번 빌드했는데, 전체 배포까지 3~4분이 걸렸다. 시안 하나 고치고 테스트할 때마다 4분씩 기다리는 건 큰 낭비였다.
가만히 지켜보던 내 머릿속에 묘수가 떠올랐다. "Vercel 배포를 기다리지 말고, Supabase Storage에 직접 올리면 1초면 되잖아?"
즉시 Supabase Storage REST API를 활용해 파일을 즉각 업로드하는 upload_to_supabase.py 모듈을 만들었다. 결과는 경이로웠다. Vercel 빌드에 걸리던 4분이 단 1초 만에 초고속으로 퍼블릭 이미지 주소를 따내는 CDN 통로로 변신했다. 복잡한 단계를 걷어내니 시스템이 비로소 제대로 숨을 쉬기 시작했다.

5. 결국 마침표를 찍은 건 내 눈의 '돋보기'
물냉면 vs 팥죽 대조 피드를 마침내 올리고 다들 성공했다며 쾌재를 불렀다. 그런데 최종 검수를 하던 내 눈에 치명적인 레이아웃 오류가 걸려들었다.
"그러고 보니 이미지에서 버튼의 글자가 반대로 쓰여져 있었네?"
다시 보니 정말 그랬다. 뜨거운 팥죽 사발 밑에 [냉면 픽!]이 깔렸고, 차가운 냉면 대접 밑에 [팥죽 패스!]가 뒤바뀌어 매핑되어 있었다. 기획자도, 디자이너도, 개발자도 속도와 자동화에 취해 놓친 픽셀 단위의 미스였다.
우리는 코드를 다시 정비하고, 나와플레이 의사결정 규칙(ADR-0002)에 '텔레그램을 통한 2단계 실물 시안 컨펌 의무화' 조항을 새로 박아 넣었다.

마치며
기술이 1초로 빨라지고 AI가 순식간에 동영상을 창조하는 시대다. 하지만 도구의 속도가 빨라질수록, 결과물을 사람의 눈 and 머리로 직접 검증하는 **'아날로그적 온도의 검수 필터'**는 더욱 절실해진다.
오늘 하루의 롤러코스터 같았던 삽질은 자동화의 속도뿐 아니라, 그 속도를 조율하는 돋보기의 귀중함을 뼈저리게 가르쳐주었다. 나와플레이의 마케팅 엔진은 이제 그 어느 때보다 빠르고, 또 안전하게 굴러가고 있다.