# Big Fact 템플릿 가이드 ## 1. 소개 숫자 하나가 화면을 채우는 통계·팩트형. 놀라운 수치를 던지고 그 의미를 설명하는 구조라 공유가 잘 된다. ## 2. 톤 가이드 숫자는 반올림해서 읽기 쉽게 쓴다(73.4% → 73%). `value` 에 수치만 넣고 단위는 `unit` 으로 분리한다. `label` 은 그 숫자가 무엇의 값인지, `body` 는 "그래서 무슨 뜻인지"를 쓴다 — 숫자를 반복 설명하지 않는다. 출처가 있으면 `source` 에 넣는다. 출처 없는 수치는 설득력이 없다. ## 3. 슬라이드 흐름 권장 `cover → fact(1~8장) → takeaway(0~2장) → cta` 순서를 지킨다. - 숫자가 3~5개일 때 가장 잘 읽힌다. 8개는 상한이지 권장이 아니다. - `takeaway` 는 숫자들을 하나의 결론으로 묶을 때만 넣는다. 없어도 된다. ## 4. 슬롯별 작성 요령 아래 슬롯 한계는 등록 시 manifest에서 자동 생성했다. design_max는 디자인 권장 상한이며 초과해도 렌더는 성공하지만 `design_max_exceeded` 경고가 발생한다. max_chars는 실측 하드 상한이며 초과하면 422 `max_chars_exceeded`가 발생한다. 다만 max_chars는 레이아웃 안전을 보장하는 값이 아니라, 같은 글자 수라도 글자 폭이나 줄바꿈에 따라 max_chars 이내에서 렌더 영역을 넘을 수 있다. 이 경우 렌더는 성공하고 결과 이미지와 함께 `text_overflow` 등의 warning을 반환하므로, 경고가 발생한 슬롯의 문구를 더 줄여 다시 렌더한다. 이 수치는 손으로 쓴 것이 아니라 manifest가 원본이다 — 본 가이드와 manifest는 영구히 일치한다. - 요청 크기: `POST /v1/renders`의 전체 JSON 요청 본문 상한은 1,048,576바이트(1MB)다. 초과하면 HTTP 413 `payload_too_large`가 발생한다. - 글쓰기 원칙: 한 슬라이드에 한 주장. 좋은 예: `API 문서를 자동으로 검증하는 법`. 나쁜 예: `정말 놀랍고 엄청난 API 문서 자동화에 관하여 알아볼까요?`. - 브랜딩: `brand_logo_url`은 프로젝트 브랜드 자산(`logo_horizontal`)으로 렌더 시 자동 공급된다. 슬롯 값으로 데이터 URI를 직접 넣지 않는다. - 색상: `accent_color`는 manifest 테마 또는 `brand.colors.accent`의 `#RRGGBB`로 자동 공급된다. - 이미지: `image` 타입 슬롯은 공개 HTTPS URL과 `data:image/;base64,...` 데이터 URI를 모두 허용한다. 실사진은 본문 상한을 피하도록 원격 HTTPS URL을 사용하고, 데이터 URI는 로고·아이콘 같은 작은 자산에만 사용한다. 슬라이드 타입별로 아래 소절을 확인한다. 슬롯 이름·필수 여부·한계값은 manifest에서 생성되며, 타입별 작성 요령은 manifest의 `slide_types[].guidance`가 원본이다. ### `cover` (min 1, max 1) 표지는 질문이나 주제를 던진다. 숫자는 다음 장부터 나온다. | 슬롯 | 필수 | 형식·한계 | | --- | --- | --- | | `eyebrow` | 아니오 | 텍스트 | | `headline` | 예 | 텍스트 | | `source` | 아니오 | 텍스트 | | `accent_color` | 아니오 | 색상(#RRGGBB, 자동 공급) | | `brand_logo_url` | 아니오 | 브랜드 자산(logo_horizontal) | | `account_name` | 아니오 | 텍스트 | ### `fact` (min 1, max 8) 숫자가 주인공이다. value 에는 수치만(예: 73), unit 에 단위(%, 배, 명). label 은 그 숫자가 무엇인지, body 는 그래서 무슨 뜻인지. | 슬롯 | 필수 | 형식·한계 | | --- | --- | --- | | `value` | 예 | 텍스트 | | `unit` | 아니오 | 텍스트 | | `label` | 예 | 텍스트 | | `body` | 예 | 텍스트 | | `source` | 아니오 | 텍스트 | | `accent_color` | 아니오 | 색상(#RRGGBB, 자동 공급) | | `brand_logo_url` | 아니오 | 브랜드 자산(logo_horizontal) | | `account_name` | 아니오 | 텍스트 | ### `takeaway` (min 0, max 2) 숫자들이 결국 무엇을 말하는지 한 문장으로 묶는다. | 슬롯 | 필수 | 형식·한계 | | --- | --- | --- | | `headline` | 예 | 텍스트 | | `body` | 예 | 텍스트 | | `accent_color` | 아니오 | 색상(#RRGGBB, 자동 공급) | | `brand_logo_url` | 아니오 | 브랜드 자산(logo_horizontal) | | `account_name` | 아니오 | 텍스트 | ### `cta` (min 1, max 1) 행동 하나만 요청한다. | 슬롯 | 필수 | 형식·한계 | | --- | --- | --- | | `headline` | 예 | 텍스트 | | `cta_text` | 예 | 텍스트 | | `accent_color` | 아니오 | 색상(#RRGGBB, 자동 공급) | | `brand_logo_url` | 아니오 | 브랜드 자산(logo_horizontal) | | `account_name` | 아니오 | 텍스트 | ## 5. 완성된 slides.json 예시 이미지 슬롯은 **공개 HTTPS URL 과 data URI 를 모두** 받는다. 실사진은 URL 을 쓴다 — 전체 JSON 요청 본문 상한이 1,048,576바이트(1MB)라 실사진을 base64 로 넣으면 두 장에서 넘어간다 (초과 시 HTTP 413 `payload_too_large`). ```json { "template": "bigfact", "format": "instagram", "slides": [ { "type": "cover", "slots": { "eyebrow": "2026 개발자 설문", "headline": "AI 도구, 실제로 얼마나 쓰고 있을까", "source": "국내 개발자 1,200명 대상", "account_name": "@lightsoft_dev" } }, { "type": "fact", "slots": { "value": "73", "unit": "%", "label": "주 5일 이상 AI 코딩 도구를 쓴다", "body": "작년 같은 조사에서는 41%였다. 1년 만에 거의 두 배가 됐다.", "source": "n=1,200", "account_name": "@lightsoft_dev" } }, { "type": "fact", "slots": { "value": "2.4", "unit": "배", "label": "코드 리뷰에 쓰는 시간이 늘었다", "body": "생성 속도가 빨라진 만큼 검토할 코드도 늘었다. 병목이 작성에서 검토로 옮겨간 셈이다.", "source": "n=1,200", "account_name": "@lightsoft_dev" } }, { "type": "takeaway", "slots": { "headline": "빨라진 건 작성이지 완성이 아니다", "body": "도구가 늘려준 시간은 검토로 되돌아왔다. 다음 병목은 리뷰다.", "account_name": "@lightsoft_dev" } }, { "type": "cta", "slots": { "headline": "이런 데이터, 매주 정리합니다", "cta_text": "팔로우", "account_name": "@lightsoft_dev" } } ] } ``` ## 6. curl 호출 예시 ```bash curl -X POST 'https://api.cardnews.example/v1/renders' \ -H 'Authorization: Bearer $CARDNEWS_API_KEY' \ -H 'Content-Type: application/json' \ --data-binary @slides.json ``` ## 7. 검증·경고 대응 가이드 - `max_chars_exceeded`: 해당 슬롯의 글자수를 줄인다. `max_chars` 는 넘기면 확실히 거부되는 상한이지 안전 보장이 아니다 — 글자가 넓으면(전각·이모지) 상한 안에서도 넘칠 수 있다. - `text_overflow` / `out_of_bounds`: 렌더는 성공하고 이미지와 함께 경고가 온다. 글자를 줄이고 다시 렌더한다. - `low_resolution`: 더 큰 원본 이미지를 쓴다. - `unknown_slot` / `missing_required_slot`: 4절의 슬롯 목록과 대조한다.