템플릿 API
템플릿은 알림 본문을 코드 배포 없이 관리하기 위한 리소스입니다.
하나의 템플릿(channel + code + name)은 여러 버전을 가지며, 그중 발행(published) 상태인 버전은 항상 1개입니다.
발송 시점에는 발행 버전의 본문이 사용되므로, 버전을 발행하는 행위가 곧 배포입니다.
개념과 변수 문법은 가이드 › 템플릿을 참고하세요.
템플릿 API는 대시보드 API에 속하며 Bearer 토큰(JWT)으로 인증합니다.
토큰 발급은 대시보드 인증을 참고하세요.
성공 응답은 별도 envelope 없이 아래 예시 그대로 반환되고, 에러는 application/problem+json 형식입니다(에러 코드 참고).
버전 상태
| 상태 | 의미 |
|---|---|
draft | 작성 중인 초안. 발송에 사용되지 않습니다. |
published | 발행본. 템플릿당 1개만 존재하며 발송에 사용됩니다. |
archived | 보관본. 새 버전이 발행되면 이전 발행본이 자동으로 이 상태가 됩니다. |
템플릿 목록 조회
워크스페이스의 템플릿을 버전 이력과 함께 모두 조회합니다. (역할: owner / admin / operator / viewer)
쿼리 파라미터는 없습니다.
필터·페이지네이션 없이 전체 목록이 생성일 오름차순으로 반환되며, 각 템플릿의 versions는 버전 번호 오름차순입니다.
{
"templates": [
{
"id": "…",
"channel": "kakao_alimtalk",
"code": "order_complete",
"name": "주문 완료 안내",
"enabled": true,
"latestVersion": { "id": "…", "version": 2, "status": "published", "contentText": "…", "variablesSchema": { "고객명": "수신자 이름" }, "createdAt": "…" },
"versions": [ … ],
"createdAt": "…",
"updatedAt": "…"
}
]
}템플릿 생성
새 템플릿을 만들며, 버전 1이 published 상태로 자동 발행되어 즉시 발송에 사용할 수 있습니다. (역할: owner / admin / operator)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
channel | string | ✓ | kakao_alimtalk sms push_fcm email slack_webhook slack_bot discord_webhook discord_bot 중 하나 |
code | string | ✓ | 발송 시 참조하는 코드. 최대 120자. 워크스페이스 내 고유 |
name | string | ✓ | 표시 이름. 최대 160자 |
contentText | string | ✓ | 본문 텍스트. 변수는 #{변수명} 표기 |
contentTitle | string | – | 제목. 최대 200자 (이메일·푸시 등) |
contentHtml | string | – | HTML 본문 (이메일) |
variablesSchema | object | – | { "변수명": "설명" } 맵. 기본 {} |
enabled | boolean | – | 기본 true |
note | string | – | 버전 메모. 최대 500자. 기본 "최초 버전" |
alimtalkTemplateId | string(UUID) | – | (kakao 채널) 이 버전이 본문을 가져온 알림톡 템플릿 ID |
curl -X POST https://api.posmit.io/v1/templates \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"channel": "sms",
"code": "order_complete",
"name": "주문 완료 안내",
"contentText": "#{고객명}님, 주문 #{주문번호} 접수가 완료되었습니다.",
"variablesSchema": { "고객명": "수신자 이름", "주문번호": "주문 번호" }
}'응답은 생성된 템플릿 1건을 담은 { "template": { … } } 형태이며, versions에 발행된 버전 1이 포함됩니다.
| 상태 | 코드 | 조건 |
|---|---|---|
| 400 | NOTI-40000 | code가 워크스페이스에 이미 존재 (Template code already exists: …) |
| 400 | NOTI-40000 | 본문 검증 실패 또는 정의되지 않은 필드 포함 |
새 버전 생성
기존 템플릿에 새 버전을 추가합니다. 버전 번호는 기존 최대 버전 + 1로 자동 부여됩니다. (역할: owner / admin / operator)
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
contentText | string | ✓ | 본문 텍스트 |
contentTitle | string | – | 제목. 최대 200자 |
contentHtml | string | – | HTML 본문 |
variablesSchema | object | – | { "변수명": "설명" } 맵. 기본 {} |
status | string | – | draft / published / archived. 기본 draft |
note | string | – | 버전 메모. 최대 500자 |
alimtalkTemplateId | string(UUID) | – | (kakao 채널) 알림톡 템플릿 ID |
status: "published"로 만들면 생성과 동시에 발행되며, 기존 발행본은 archived로 전환됩니다.
{
"version": {
"id": "…",
"version": 3,
"status": "draft",
"contentText": "…",
"contentTitle": null,
"contentHtml": null,
"variablesSchema": { "고객명": "수신자 이름" },
"createdAt": "…"
}
}| 상태 | 코드 | 조건 |
|---|---|---|
| 404 | NOTI-40400 | templateId가 없거나 다른 워크스페이스 소유 |
| 400 | NOTI-40000 | 본문 검증 실패, 또는 templateId가 UUID 형식이 아님 |
버전 발행
지정한 버전을 발행하며, 요청 본문은 없습니다. (역할: owner / admin / operator)
발행 버전은 템플릿당 1개만 유지되므로, 기존 published 버전은 자동으로 archived로 전환됩니다.
응답은 새 버전 생성과 동일한 { "version": { …, "status": "published" } } 형태입니다.
| 상태 | 코드 | 조건 |
|---|---|---|
| 404 | NOTI-40400 | 템플릿 또는 버전이 없거나 다른 워크스페이스 소유 |
AI 템플릿 생성
의도(자연어)를 입력하면 LLM이 채널에 맞는 템플릿 초안을 생성합니다. (역할: owner / admin / operator)
생성 결과는 자동으로 저장되지 않으며, 후보를 검토·수정한 뒤 POST /v1/templates 또는 새 버전 생성으로 직접 저장해야 합니다.
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
channel | string | ✓ | 대상 채널 (템플릿 생성과 동일한 8개 값) |
intent | string | ✓ | 만들고 싶은 메시지의 의도. 최대 2,000자 |
tone | string | – | 말투/톤 (예: "정중하게"). 최대 100자 |
variableHints | string[] | – | 포함할 변수 힌트 (예: ["고객명", "주문번호"]). 최대 20개 |
model | string | – | 모델명 단건 지정 (예: "gpt-5"). 없으면 채널 기본 모델 사용 |
curl -X POST https://api.posmit.io/v1/ai/templates/generate \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"channel": "kakao_alimtalk",
"intent": "주문 완료를 안내하고 배송 조회를 유도",
"tone": "정중하게",
"variableHints": ["고객명", "주문번호"]
}'{
"modelRef": { "provider": "vertex", "model": "gemini-2.5-flash" },
"template": {
"contentText": "#{고객명}님, 주문 #{주문번호} 결제가 완료되었습니다. …",
"contentTitle": null,
"contentHtml": null,
"variablesSchema": { "고객명": "수신자 이름", "주문번호": "주문 번호" }
},
"validation": { "ok": true, "violations": [] }
}| 상태 | 코드 | 조건 |
|---|---|---|
| 400 | NOTI-40000 | model이 카탈로그에 없거나 해당 채널을 지원하지 않음 |
| 502 | NOTI-50200 | AI 공급자 호출 실패 |
모델 카탈로그
채널에서 사용 가능한 모델 목록을 조회합니다.
channel 쿼리 파라미터는 필수이며, 유효하지 않으면 400이 반환됩니다.
응답은 { "models": [ { "model", "provider", "label", "channels", "recommended?" } ] } 형태입니다. (역할: owner / admin / operator / viewer)
| 모델 | 공급자 | 지원 채널 |
|---|---|---|
gemini-2.5-flash-lite | vertex | 텍스트 채널* + kakao_alimtalk |
gpt-5-nano | openai | 텍스트 채널* |
gemini-2.5-flash | vertex | 전체 채널 |
gpt-5 | openai | 전체 채널 |
claude-sonnet-4-6 | anthropic | email, kakao_alimtalk |
claude-opus-4-8 | anthropic | email |
* 텍스트 채널: sms, push_fcm, slack_webhook, slack_bot, discord_webhook, discord_bot
model을 지정하지 않았을 때의 채널 기본 모델은 다음과 같습니다.
| 채널 | 기본 모델 |
|---|---|
| 텍스트 채널* | gemini-2.5-flash-lite |
kakao_alimtalk | gemini-2.5-flash |
email | gpt-5 |
자동 검증 violation 코드
생성 결과는 저장 전에 결정론적으로 사전 검증되며, 결과가 validation.violations에 담깁니다.
severity: "error"가 하나라도 있으면 validation.ok가 false이며(발송·검수 차단 수준), warning은 권고입니다.
| 코드 | 수준 | 의미 |
|---|---|---|
variable_undeclared | warning | 본문의 #{변수}가 variablesSchema에 선언되지 않음 |
variable_unused | warning | variablesSchema의 변수가 본문에 사용되지 않음 |
kakao_too_long | error | 알림톡 본문이 1,000자 초과 |
kakao_variable_only | error | 변수·공백을 제외한 고정 문구가 10자 미만 — 검수 반려 위험 |
kakao_ad_like | error | 광고성 표현 포함(할인·이벤트·쿠폰 등) — 알림톡은 정보성만 허용 |
sms_too_long | error | 본문이 LMS 한도(2,000바이트, EUC-KR 근사) 초과 |
sms_lms | warning | 본문이 90바이트 초과 — SMS가 아닌 LMS로 발송됨 |
email_no_html | error | 이메일인데 contentHtml이 비어 있음 |
email_no_title | warning | 이메일 제목(contentTitle)이 비어 있음 |
발송에서 사용하기
등록한 템플릿은 알림 API에서 content.templateCode로 참조합니다.
알림 발송 API › 템플릿 발송을 참고하세요.