자매편 PDF 속성에는 남의 도구가 아니라 자사 브랜드가 찍혀야 합니다가 PDF 메타데이터에 신경 써야 하는 이유를 다뤘다면, 이 글은 운용 매뉴얼입니다. 각 필드가 PDF 사양에서 무엇을 위한 것인지, 누가 읽는지, 흔한 실수는 무엇인지, 그리고 의도한 내용이 실제로 출고되었는지 어떻게 검증하는지 설명합니다.
gPdf는 PDF 사양이 문서 수준 메타데이터로 정의한 6개의 표준 필드를 노출합니다. DocumentRequest JSON의 settings.metadata 아래에 자리합니다. 모든 필드는 선택입니다 —— 설정하지 않으면 gPdf는 토큰의 default_metadata(Enterprise 정책 기능) 또는 시스템 기본값을 대신 사용합니다.
{
"settings": {
"metadata": {
"title": "...",
"language": "...",
"author": "...",
"subject": "...",
"creator": "...",
"producer": "..."
}
}
}
이 글의 나머지는 한 섹션당 한 필드입니다. 각 섹션은 동일한 형식을 따릅니다: 이 필드는 무엇인지, 어디에 표면화되는지, 흔한 실수, 경험 법칙. 순서는 먼저 채울 것 → 다음 → … → 마지막 채울 것 순서입니다.
title —— 문서가 무엇인가
PDF 사양은 이것을 “문서 제목“으로 설명합니다.
어디에 표면화되는가:
- PDF 뷰어의 타이틀바(Adobe Reader, Preview, Foxit, Chromium PDF 뷰어 모두 표시).
- 인라인으로 열렸을 때(
Content-Disposition: inline) 브라우저 탭. - 검색 인덱스 —— Spotlight, Outlook, SharePoint, Google Drive의 풀텍스트 인덱서 모두
title을 읽고 가중치를 크게 줍니다.
흔한 실수:
- ❌ title을 파일명으로 설정.
invoice-20260318.pdf는 파일명입니다. title은 사람이 읽는 문자열, 예컨대Invoice INV-2026-3401이어야 합니다. 파일명과 제목은 다른 관심사입니다: 파일명은 파일 시스템용, 제목은 뷰어와 검색용. - ❌ title을 빈 채로 둠. 뷰어는 파일명으로 대신 표시합니다. 결과적으로 자동 생성된, 기계가 뱉은 인상으로 읽힙니다.
- ❌ title에 브랜드를 섞음.
Acme Logistics — Invoice INV-2026-3401는 타이틀바를 어지럽힙니다. 브랜드의 자리는author이지title이 아닙니다.
경험 법칙: title은 렌더링된 페이지의 H1과 일치해야 합니다. 청구서 템플릿 최상단 줄이 “Invoice INV-2026-3401“이라면, 그것이 title입니다.
language —— 접근성, 검색, 컴플라이언스를 위해
language는 BCP-47 언어 태그입니다: en, de, zh-Hans, pt-BR, ar-SA. 모든 문서에 설정하십시오. 6개 필드 중 후속 시스템에 미치는 영향이 가장 구체적이고 구현 비용이 가장 작습니다 —— 그래서 맨 아래에 묻히지 않고 2번 자리에 있습니다.
어디에 표면화되는가:
- 스크린 리더 —— JAWS, NVDA, VoiceOver가 이것을 사용해 올바른 음소 집합을 고릅니다. 영어 스크린 리더가
language: "de"PDF를 읽을 때 독일어 단어를 올바르게 발음합니다. 태그가 없으면 운율이 어긋납니다. - 검색 엔진과 인덱서 —— 어떤 로케일의 어간 추출과 불용어 목록을 적용할지 결정합니다.
language: "zh-Hans"청구서는 중국어 세그멘테이션으로 인덱싱됩니다. 태그가 없으면 대개 영어가 기본값이 되어 인덱스가 쓸모없어집니다. - PDF/A 준수 —— PDF/A-2a와 PDF/A-3a(접근성 프로필)는 언어 태그를 요구합니다. 없으면 veraPDF 검증이 바로 실패합니다.
흔한 실수:
- ❌ 설정하지 않음. 기본값은 “수신자 로케일“이지 “플랫폼 기본“이 아닙니다. 허술한 스택 대부분은 이 필드를 아예 쓰지 않습니다. 결과는 발음을 틀리는 스크린 리더와, 어간을 잘못 잡는 검색 인덱스입니다.
- ❌ 비-BCP-47 문자열, 예컨대
"english"나"EN-US". PDF 사양은 RFC 5646 태그를 기대합니다:en,en-US,de,pt-BR. - ❌ 문서의 실제 콘텐츠 언어와 무관하게 플랫폼 기본(예: 항상
"en")을 하드코딩. 포르투갈어 청구서를"en"으로 태그하는 것은 무태그보다 나쁩니다 —— 인덱서를 적극적으로 호도합니다.
경험 법칙: 태그는 실제 콘텐츠 언어와 일치해야 합니다. 브라질 고객이 포르투갈어로 받는 청구서라면 "language": "pt-BR"로 설정하지, "en"이 아닙니다. 다국어 문서라면 주된 언어를 고르고, 나머지는 개별 콘텐츠 요소에 Lang 속성을 사용하십시오 —— 그건 문서 수준 language 필드를 넘어서는 태그드 PDF 접근성 기능입니다.
author —— 문서를 누구와 연결해야 하나
PDF 사양에서 author는 “문서를 만든 개인 또는 조직의 이름“입니다. 수신자에게 전달되는 업무 PDF에서는 답은 거의 항상 조직입니다 —— 다만 적절한 형태는 맥락에 따라 진짜로 다릅니다.
어디에 표면화되는가:
- 모든 PDF 뷰어의 속성 대화창. “Author” 라벨로 두드러지게.
- DMS / 아카이브 인덱서. 종종 필터로 사용.
- PDF/A의 XMP 메타데이터 스트림. 장기 아카이브까지 운반됩니다.
흔한 실수:
- ❌
"author": "[email protected]"—— 운용자의 이메일을 모든 PDF에 흘려보내고, 모든 검색 인덱스에 들어가며, 장기 PII 이슈가 됩니다. - ❌
"author": "PDF Generator Service"—— 내부 도구명이며 수신자에게는 아무 의미가 없습니다. - ❌ 빈 값 —— Preview와 대다수 뷰어는 속성 대화창에 그대로 “(no author)“라고 표시하며, “이 문서의 책임 주체가 없다“로 읽힙니다.
작동하는 형태:
- ✅
"author": "Acme Logistics, Inc."—— 직설적인 조직. - ✅
"author": "Acme Logistics — Billing"—— 조직 + 부서. 특정 데스크로 흘러가는 문서에 적합. - ✅
"author": "Bridge Capital Partners — Fund III"—— 귀속이 특정 실체로 가는 금융 / 법무에서 유용. - ✅
"author": "Maria López, RICS Surveyor"—— 단독 저자 출판(리포트, 감정, 법률 의견)에서 개인 자체가 편집상의 귀속인 경우.
경험 법칙: author는 수신자가 문서와 연결해야 하는 실체입니다. 플랫폼이 고객을 대신해 PDF를 만드는 멀티 테넌트 SaaS에서, author는 플랫폼 이름이 아니라 고객의 조직 이름이어야 합니다. (플랫폼 이름의 자리는 creator —— 아래 참조.) 컨설팅 / 출판 / 법무처럼 개인 자체가 브랜드인 맥락이라면 개인도 괜찮습니다.
subject —— 이 문서는 어떤 종류인가
subject는 문서의 짧은 설명입니다. 뷰어는 두드러지게 보여주지 않습니다 —— 속성 대화창을 열지 않는 한 대부분의 사용자는 보지 못합니다. 그러나 문서 관리 시스템, 아카이브 시스템, 규칙 기반 메일 / 파일 라우팅은 이를 사용합니다.
어디에 표면화되는가:
- 속성 대화창의 보조 위치.
- DMS 라우팅 규칙, 아카이브 분류 로직.
- XMP 메타데이터 스트림(PDF/A).
흔한 실수:
- ❌
"subject": "Invoice for Acme on 2026-03-18 for $4,532.10"—— 이건 문서 인스턴스 설명이지 유형이 아닙니다.title의 영역입니다. - ❌ 빈 값 —— 후속 시스템에 줄 수 있는 공짜 라우팅 훅을 낭비합니다.
- ❌ 분류를 일관성 없이 섞기(
"Invoice"vs"Invoice/2026-03"vs"Monthly invoice") —— DMS 필터는 움직이는 타깃에 대해 버킷팅할 수 없습니다.
작동하는 형태:
- ✅
"subject": "Invoice" - ✅
"subject": "Monthly account statement" - ✅
"subject": "Shipping label — 4×6 thermal" - ✅
"subject": "Q3 2026 board pack"
경험 법칙: 적절한 입도는 문서 클래스이지 문서 인스턴스가 아닙니다. 매일 수천 건의 PDF가 들어오는 DMS는 일관된 어휘만 주어지면 subject로 라우팅할 수 있습니다. 플랫폼에 유한한 클래스 집합을 정하고 절대 어기지 마십시오 —— 플랫폼이 발행하는 모든 청구서는 정확히 "subject": "Invoice"이어야 합니다.
creator vs producer —— 가장 헷갈리는 한 쌍
여기서 대다수 팀은 PDF 사양 읽기를 멈추고 추측에 들어갑니다. 사양은 명확합니다: 두 필드는 다른 것을 의미합니다.
creator—— 원본 콘텐츠를 만든 애플리케이션(문서가 무엇을 말해야 하는지 정한 상위 시스템).producer—— PDF 바이트를 만든 애플리케이션(그 콘텐츠를 PDF 파일로 바꾼 PDF 생성 엔진).
gPdf 같은 JSON-PDF 변환 API를 통해 청구서를 만드는 SaaS 청구 플랫폼이라면:
creator= 버전이 붙은 SaaS 청구 플랫폼. 바로 이 애플리케이션이 이게 Acme에게 발행할 4,532.10달러짜리 청구서여야 한다고 결정했습니다.producer= PDF 생성기. 기본은 “gPdf“입니다. 그러나 PDF 생성 계층은 SaaS가 선택한 인프라이므로, SaaS는producer를 자사 플랫폼명으로 정당하게 설정할 수 있습니다 —— 실질적인 의미에서 그 SaaS의 플랫폼이 인프라로서의 gPdf에 위임하여 PDF 바이트를 만들었기 때문입니다.
{
"creator": "Acme Billing Platform v7.2",
"producer": "Acme Billing Platform"
}
어디에 표면화되는가:
- 속성 대화창. 둘 다 라벨링됨.
pdfinfo출력에서 나란히.- PDF/A의 XMP 스트림(PDF/A에서 두 필드 모두 비어 있어서는 안 됨).
흔한 실수:
- ❌
creator에 Chromium / Mozilla User-Agent 문자열이 들어감. 헤드리스 브라우저 PDF 스택이 User-Agent를 자동으로creator에 넣을 때 발생합니다. 그건 브라우저 버전이지 문서 내용을 결정한 기준 시스템이 아닙니다. 덮어쓰십시오. - ❌
producer가 기본 PDF 생성기 이름인 채로 남음. 대다수 팀은 절대 이걸 덮어쓰지 않아 모든 PDF가 “Skia/PDF m120“이나 “wkhtmltopdf“라고 말합니다 —— 이게 B2B에서 왜 중요한지는 화이트 라벨 편을 보십시오. - ❌ 두 필드에 같은 값을 넣음. 허용되지만 낭비입니다 —— 두 필드가 따로 존재하는 이유가 바로 뷰어가 “기준 콘텐츠를 만든 앱“과 “PDF 생성 엔진“을 구분할 수 있게 하기 위함입니다. 활용하십시오.
경험 법칙: creator는 앱 이름 + 버전(예: "Acme Billing Platform v7.2"); producer는 앱의 브랜드 또는 플랫폼 이름 버전 없이(예: "Acme Billing Platform"). 둘 다 수신자가 알아볼 수 있는 값이어야 합니다.
빈 필드, 토큰별 기본값, 후속 처리의 의외성
출하 전에 알아두면 좋은 구현 세부 사항 셋:
- 빈 문자열이나 공백뿐인 문자열은 미제공으로 취급됩니다.
"title": ""를 보내는 것은title을 생략하는 것과 동등합니다 —— 빈 문자열을 PDF에 쓰지 않고, 대체값 흐름(토큰 기본값 → 시스템 기본값)을 따라갑니다. “설정했는데 적용 안 됨” 류의 가장 흔한 버그 리포트 원인이 이것입니다. - 토큰 정책이 메타데이터 필드를 제거하거나 기본값을 지정할 수 있습니다. gPdf를 사용하는 멀티 테넌트 SaaS는 각 API 토큰에
default_metadata를 설정할 수 있고, 그러면 그 토큰이 만드는 모든 PDF는 모든 개발자가 요청마다 설정한다고 믿지 않고도 고객의author와producer를 자동으로 갖게 됩니다. “모든 Acme PDF는 Acme라고 말해야 한다“의 올바른 강제 레이어가 토큰 수준 기본값입니다. - 후속 처리 경로가 메타데이터를 다시 쓸 수 있습니다. gPdf 반환 후 PDF를 후처리하는 도구 —— 명시적인 메타데이터 보존 플래그가 없는 Ghostscript, 일부 기업 DRM 도구, 일부 “PDF 옵티마이저” —— 가 Producer를 자기 이름으로 덮어쓰고 방금 설정한 브랜딩을 무효화할 수 있습니다. 원시 gPdf 응답이 아니라 실제 운영 처리 경로에 대해 검증하십시오.
메타데이터 검증하기
위 변경을 구현한 후, PDF가 의도한 내용을 실제로 출고했는지 빠르게 확인하는 세 가지 방법:
커맨드라인(macOS / Linux, poppler-utils 필요):
$ pdfinfo your-output.pdf | head -10
Title: Invoice INV-2026-3401
Subject: Monthly invoice — 2026-03
Author: Acme Logistics, Inc.
Creator: Acme Billing Platform v7.2
Producer: Acme Billing Platform
Language: en
Acrobat / Adobe Reader: 파일 → 속성 → 설명 탭. 6개 필드가 모두 나타나며 Title은 뷰어 상단 타이틀바에도 표시됩니다.
macOS Preview: ⌘+I(정보 가져오기). “PDF” 인스펙터 패널에 같은 필드들이 나타납니다.
어떤 필드든 비어 있거나 공백이거나 설정한 적 없는 도구명이 보이면, 요청 본문을 되짚어 보십시오 —— 가장 흔한 원인은 ""(빈 문자열) 전송이며, API는 이를 “미제공“으로 처리해 대체값 흐름을 따라 어떤 기본값에 닿게 됩니다. 두 번째로 흔한 원인은 후속 처리 경로(Ghostscript, DRM, 옵티마이저)가 gPdf 반환 이후에 필드를 덮어쓰는 경우입니다. 원시 생성 응답만이 아니라 운영 환경을 상대로 테스트하십시오.
PDF/A 아카이브에서의 메타데이터
장기 아카이브를 위해 settings.profile: "pdfa-2b"(혹은 -2a, -3a, -3b)로 생성한다면, 메타데이터는 더 이상 선택이 아니라 보존 품질을 지탱하는 필수 요소가 됩니다:
- PDF/A 준수 파일에서
producer필드는 비어 있을 수 없습니다 —— 최소한 시스템 기본값이 실립니다. - 접근성 프로필(PDF/A-2a, PDF/A-3a)은
language를 요구합니다. 없으면 veraPDF 검증이 곧장 떨어집니다. - PDF/A가 요구하는 XMP 메타데이터 스트림은 위의 6개 필드로부터 자동 생성됩니다. 직접 구성할 필요가 없습니다.
title,author,subject,creator,producer,language모두 XMP 스트림에 실리므로, 후속 아카이브의 메타데이터 인덱서(Preservica, Archivematica)는 본문을 다시 파싱하지 않고도 카탈로그를 구축할 수 있습니다.
아카이브 문서에서 브랜드 메타데이터는 단순한 브랜드 다듬기가 아니라, 산출물의 내구성 일부입니다. 10년 뒤 여러분의 PDF를 여는 독일 세관, 브라질 세무 당국, 또는 임의의 장기 아카이브가 보게 되는 것은 생성한 그날 그 필드들에 들어 있던 내용 그대로입니다. 생성 시점에 의도적으로 설정하는 것이 주어진 유일한 기회입니다.
gPdf가 아직 노출하지 않는 것
현재 제공 범위를 솔직히 말하자면: PDF 사양은 Keywords(자유 형식 검색어)와 임의의 사용자 정의 키-값을 지원하는 XMP 메타데이터 스트림도 정의합니다. 현재 API에서 gPdf는 둘 다 노출하지 않습니다.
PDF 내부에 임의의 비즈니스 데이터(주문 UUID, 창고 코드, 템플릿 버전)를 보관해야 한다면 오늘의 우회책은:
subject를 후속 시스템이 파싱하는 구조화된 짧은 문자열로 설정.- 비즈니스 데이터는 파일명이나 콘텐츠 해시를 키로 자사 DB에 보관.
- 기다리기 —— XMP 사용자 정의 필드는 로드맵에 있으며, 출하되면 숨겨진 기계 판독용 업무 맥락의 올바른 답이 됩니다.
“브랜드 메타데이터”(오늘 있는 6개 표준 필드)와 “사용자 정의 비즈니스 메타데이터”(미래의 XMP 사용자 정의 필드)를 혼동하는 게 오늘 가능한 것을 가장 쉽게 과대 약속하는 방식입니다. 자체 기획에서도 분리해 두는 게 좋습니다.
완전한 예시
SaaS 청구 플랫폼(Acme Billing Platform)이 독일 고객(Müller Versand GmbH)에게 청구서를 만들고, PDF/A로 아카이브할 준비를 합니다:
{
"settings": {
"profile": "pdfa-3b",
"metadata": {
"title": "Rechnung RE-2026-0412",
"language": "de",
"author": "Müller Versand GmbH",
"subject": "Monatsrechnung — März 2026",
"creator": "Acme Billing Platform v7.2",
"producer": "Acme Billing Platform"
}
}
}
생성된 PDF에 대한 pdfinfo:
$ pdfinfo invoice-2026-0412.pdf | head -10
Title: Rechnung RE-2026-0412
Subject: Monatsrechnung — März 2026
Author: Müller Versand GmbH
Creator: Acme Billing Platform v7.2
Producer: Acme Billing Platform
Language: de
제목은 독일어, author는 Müller Versand(고객의 GmbH 법인이자 문서 수신자), creator는 Acme Billing Platform(페이지에 무엇을 넣을지 결정한 기준 시스템), producer는 Acme Billing Platform의 브랜드, language는 독일어 스크린 리더와 나중에 Müller의 DMS에서 이 문서를 집어갈 독일어 풀텍스트 인덱서를 위해 정확히 태그됩니다. PDF/A-3b 프로필이므로 이 메타데이터 집합은 장기 아카이브를 위해 XMP 스트림에도 직렬화됩니다.
파일 속성 어디에도 gPdf, Chromium, 고객이 선택하지 않은 도구의 이름은 등장하지 않습니다 —— 바로 그것이 요점입니다.
가능한 가장 작은 업그레이드
이미 /api/v1/pdf/render로 POST하고 있고 현재 호출에 settings.metadata가 없다면, 가장 작은 개선은 이미 보내고 있는 JSON에 세 줄을 추가하는 것입니다:
{
"pages": [...],
"settings": {
+ "metadata": {
+ "author": "Your customer's organisation",
+ "producer": "Your platform"
+ }
}
}
두 필드, 새 키 하나. pdfinfo로 몇 초면 검증할 수 있습니다. 이게 들어간 다음에 시간이 될 때 title, language, subject, creator를 채우면 됩니다.
이 주제가 닿는 곳
- §4.14.2 Metadata —— 이 필드들의 API 레퍼런스.
- PDF 화이트 라벨링(자매편) —— 왜 그래야 하는지와 B2B SaaS 사례.
- 엔지니어를 위한 PDF/A와 Factur-X 설명 —— 메타데이터 이야기에 장기 아카이브가 포함된다면 관련 있습니다.