캠페인 API
알림톡 캠페인을 생성·조회하고, 제목·상태·발송 설정·기존 템플릿·상품필터를 안전하게 변경합니다.
revision을 If-Match 헤더로 보내야 합니다.
그 사이 콘솔이나 다른 요청이 설정을 바꾸면 4092로 거절됩니다. 최신 상태를 다시 조회한 뒤 재시도하세요.
공통 요청 정보
https://docs.almani-center.com/open/v1
Bearer ak_live_xxxx 형식의 API 키입니다. 조회는 campaign:read, 변경은 campaign:write 스코프가 필요합니다.
캠페인이 속한 알마니 사이트 ID입니다. 다른 사이트의 캠페인은 존재 여부를 노출하지 않고 4040을 반환합니다.
조회 응답의 revision입니다. 상태·캠페인 설정·템플릿 변경에는 cp_, 상품필터 PATCH·PUT에는 pf_ revision을 사용합니다. 생성 요청에는 사용하지 않습니다.
네트워크 재시도로 같은 캠페인이 중복 생성되지 않도록 요청마다 고유한 값을 사용합니다. 수정 요청에도 사용을 권장합니다. 최대 100자이며 동일 키에 다른 요청 본문을 사용할 수 없습니다.
cp_ revision은 상태·캠페인 설정·템플릿용이고, 상품필터 조회의 pf_ revision은 상품필터용입니다.
서로 바꿔 보내면 4092가 반환됩니다.
권장 작업 순서
- 상품 검색으로 추가할
productId와 옵션을 확인합니다. - 캠페인 또는 상품필터를 조회해 현재 조건과
revision을 저장합니다. - 조회한 revision을
If-Match에 넣고 고유한Idempotency-Key와 함께 변경 요청을 보냅니다. - 적용 후 다시 조회해 캠페인 설정과 상품 수를 확인합니다.
캠페인 생성
/campaigns필요 스코프: campaign:write
사이트에서 사용할 수 있는 트리거와 기존 승인 템플릿으로 새 알림톡 캠페인을 만듭니다.
active는 항상 false입니다.
생성 결과를 확인한 뒤 응답의 revision으로 캠페인 켜기·끄기 API를 호출하세요.
Request Body
콘솔에 표시할 제목입니다. 최대 200자이며 같은 사이트의 미삭제 캠페인 제목과 중복될 수 없습니다. 앞뒤 공백과 영문 대소문자는 중복 검사에서 구분하지 않습니다.
결제 완료·배송 시작 등 발송 트리거 코드입니다. 현재 사이트 전용 또는 사이트 플랫폼에서 활성화된 트리거만 사용할 수 있습니다.
해당 사이트에서 사용할 수 있는 승인(APR)·활성(A) 템플릿 코드입니다. 템플릿의 변수 매핑과 이미지 유형을 캠페인에 적용합니다.
type은 IMMEDIATE 또는 DELAYED입니다. 지연 발송이면 delay.unit(MINUTE/HOUR/DAY)과 1 이상의 delay.value가 필요합니다.
상품필터 전체 교체와 같은 mode·groupJoin·groups 구조입니다. 생략하거나 null이면 모든 상품이 대상입니다. 상품과 옵션은 현재 사이트 데이터로 검증합니다.
생략하면 발송 제한시간을 사용하지 않습니다. 활성화 시 start, end, behavior가 필요합니다.
관리자 발송 사용 여부이며 기본값은 false입니다.
저장 전에 플랫폼·트리거 정합성, 발신프로필 상태, 템플릿 승인·활성 상태, 상품과 옵션을 모두 검사합니다. 하나라도 유효하지 않으면 캠페인은 생성되지 않습니다.
curl -X POST "https://docs.almani-center.com/open/v1/campaigns" \
-H "Authorization: Bearer ak_live_xxxx" \
-H "X-Site-Id: 467" \
-H "Idempotency-Key: 864ba612-5c53-4f08-9d12-3029b4d9e272" \
-H "Content-Type: application/json" \
-d '{
"title": "결제 완료 고객 안내",
"triggerEvent": "cafe24Purchase",
"templateCode": "TPL_4593319557",
"sendTiming": {
"type": "DELAYED",
"delay": {"unit": "HOUR", "value": 1}
},
"productFilter": {
"mode": "INCLUDE",
"groupJoin": "OR",
"groups": [{
"operator": "OR",
"products": [
{"productId": "27", "variantIds": []},
{"productId": "49", "variantIds": ["49-A"]}
]
}]
}
}'{
"campaignId": 8112,
"title": "결제 완료 고객 안내",
"active": false,
"triggerEvent": "cafe24Purchase",
"channel": "AT",
"template": {
"templateCode": "TPL_4593319557",
"templateName": "결제 완료 안내",
"approveStatus": "APR",
"templateStatus": "A",
"sendable": true
},
"settings": {
"sendTiming": {"type":"DELAYED","delay":{"unit":"HOUR","value":1}},
"quietHours": {"enabled":false,"start":null,"end":null,"behavior":null},
"adminSendEnabled": false
},
"productFilterSummary": {
"mode":"INCLUDE","groupCount":1,"productCount":2,"variantCount":1
},
"revision": "cp_3eb7...",
"createdAt": "2026-09-04T16:20:00+09:00"
}캠페인 목록 조회
/campaigns필요 스코프: campaign:read
선택한 사이트의 자동 알림톡 캠페인만 반환합니다. 테스트 캠페인과 직접 API 발송용 캠페인은 제외됩니다.
Query 파라미터
활성 여부 필터.
결제완료·배송시작 등 저장된 트리거 코드의 정확 일치.
현재 사용 중인 템플릿 코드.
상품필터 저장 여부.
제목 또는 캠페인 ID 검색과 커서 페이지네이션. 기본 20, 최대 100.
주요 응답 필드
캠페인 ID와 콘솔에 표시되는 제목입니다.
활성 여부, 트리거 이벤트와 채널 코드(AT 또는 AI)입니다.
현재 템플릿의 코드·이름·승인 상태·활성 상태와 발송 가능 여부입니다.
필터 모드와 그룹·상품·지정 옵션 수를 요약합니다.
제목·상태·설정·템플릿 변경에 사용할 cp_ revision입니다.
다음 페이지가 없으면 null입니다.
curl "https://docs.almani-center.com/open/v1/campaigns?active=true" \
-H "Authorization: Bearer ak_live_xxxx" \
-H "X-Site-Id: 467"{
"code": "0000",
"data": {
"items": [{
"campaignId": 3541,
"title": "결제 완료",
"active": true,
"triggerEvent": "PAY_COMPLETE",
"channel": "AT",
"template": {
"templateCode": "MEARI_ORDER",
"templateName": "주문 안내",
"approveStatus": "APR",
"templateStatus": "A",
"sendable": true
},
"productFilterSummary": {
"mode": "INCLUDE",
"groupCount": 1,
"productCount": 1,
"variantCount": 0
},
"revision": "cp_91a3..."
}],
"nextCursor": null
}
}캠페인 상세 조회
/campaigns/{campaignId}필요 스코프: campaign:read
제목, 상태, 트리거, 현재 템플릿과 발송 설정을 조회합니다. 반환된 revision은 제목·상태·설정·템플릿 변경의 If-Match 값입니다.
settings.sendTiming.type은 IMMEDIATE 또는 DELAYED, 제한시간 처리 방식은 QUEUE 또는 CANCEL입니다.
curl "https://docs.almani-center.com/open/v1/campaigns/3541" \
-H "Authorization: Bearer ak_live_xxxx" \
-H "X-Site-Id: 467"{
"campaignId": 3541,
"title": "결제 완료",
"content": "#{고객명}님, 주문이 완료되었습니다.",
"active": true,
"triggerEvent": "PAY_COMPLETE",
"channel": "AT",
"template": {
"templateCode": "MEARI_ORDER",
"approveStatus": "APR",
"templateStatus": "A",
"sendable": true
},
"settings": {
"sendTiming": {"type":"IMMEDIATE","delay":null},
"quietHours": {
"enabled": true,
"start": "21:00",
"end": "08:00",
"behavior": "QUEUE"
},
"adminSendEnabled": true
},
"productFilterSummary": {
"mode":"INCLUDE",
"groupCount":1,
"productCount":1,
"variantCount":0
},
"revision": "cp_91a3...",
"createdAt": "2026-08-01T10:00:00+09:00",
"updatedAt": "2026-08-29T10:20:00+09:00"
}캠페인 켜기·끄기
/campaigns/{campaignId}/status필요 스코프: campaign:write
active만 변경합니다. 활성화할 때는 발신프로필, 승인·활성 템플릿, 상품과 옵션의 유효성을 다시 검증합니다.
Request Body
true면 활성화하고 false면 중지합니다. 현재 값과 같으면 성공 응답의 result가 UNCHANGED입니다.
true로 바꿀 때 발신프로필·템플릿·상품·옵션 중 하나라도 사용할 수 없으면 4222로 거절되며 상태는 바뀌지 않습니다.curl -X PATCH "https://docs.almani-center.com/open/v1/campaigns/3541/status" \
-H "Authorization: Bearer ak_live_xxxx" \
-H "X-Site-Id: 467" \
-H "If-Match: cp_91a3..." \
-H "Idempotency-Key: 4ea45671-7b3d-44cc-84be-75cae7681109" \
-H "Content-Type: application/json" \
-d '{"active":false}'{
"campaignId": 3541,
"previousActive": true,
"active": false,
"result": "UPDATED",
"revision": "cp_a44d...",
"updatedAt": "2026-08-29T11:10:00+09:00"
}캠페인 설정 변경
/campaigns/{campaignId}/settings필요 스코프: campaign:write
캠페인 제목, 발송 시점, 발송 제한시간, 관리자 발송 사용 여부 중 보낸 항목만 변경합니다. 트리거 이벤트는 이 API로 변경할 수 없습니다.
새 캠페인 제목입니다. 앞뒤 공백을 제거한 뒤 최대 200자까지 저장합니다. 같은 사이트의 미삭제 캠페인과 중복될 수 없으며 공백과 영문 대소문자는 구분하지 않습니다.
지연 발송이면 delay.unit(MINUTE/HOUR/DAY)과 1 이상의 delay.value가 필요합니다.
활성화 시 start, end(HH:mm), behavior(QUEUE/CANCEL)가 모두 필요합니다.
관리자 직접 발송 사용 여부입니다.
네 항목 중 하나 이상을 보내야 하며, 보내지 않은 설정은 기존 값을 유지합니다. 다른 사이트에는 같은 캠페인 제목을 사용할 수 있습니다.
curl -X PATCH "https://docs.almani-center.com/open/v1/campaigns/3541/settings" \
-H "Authorization: Bearer ak_live_xxxx" \
-H "X-Site-Id: 467" \
-H "If-Match: cp_91a3..." \
-H "Idempotency-Key: 42aba62d-3fb4-42d7-8d50-3a0ab2f2a790" \
-H "Content-Type: application/json" \
-d '{
"title": "결제 완료 고객 안내",
"sendTiming": {
"type": "DELAYED",
"delay": {"unit": "HOUR", "value": 1}
},
"quietHours": {
"enabled": true,
"start": "21:00",
"end": "08:00",
"behavior": "QUEUE"
},
"adminSendEnabled": true
}'{
"campaignId": 3541,
"result": "UPDATED",
"revision": "cp_0d32...",
"updatedAt": "2026-08-29T11:15:00+09:00"
}캠페인에서 사용할 템플릿 변경
/campaigns/{campaignId}/template필요 스코프: campaign:write
해당 사이트에서 사용할 수 있는 승인(APR)·활성(A) 템플릿만 지정할 수 있습니다. 다른 템플릿으로 교체하면 선택한 템플릿의 현재 변수 매핑과 이미지 유형을 캠페인에 적용합니다.
사용할 템플릿은 먼저 템플릿 목록 조회에서 승인 상태와 코드를 확인하세요.
Request Body
같은 사이트에서 사용할 수 있는 승인·활성 템플릿 코드입니다. 최대 100자입니다.
templateCode이면 UNCHANGED를 반환하고 기존 캠페인 변수 매핑을 건드리지 않습니다.curl -X PATCH "https://docs.almani-center.com/open/v1/campaigns/3541/template" \
-H "Authorization: Bearer ak_live_xxxx" \
-H "X-Site-Id: 467" \
-H "If-Match: cp_91a3..." \
-H "Idempotency-Key: c7e55bf9-0d82-424c-948d-d606f0fe28b7" \
-H "Content-Type: application/json" \
-d '{"templateCode":"MEARI_SHIPPING"}'{
"campaignId": 3541,
"result": "UPDATED",
"revision": "cp_602b...",
"updatedAt": "2026-08-29T11:20:00+09:00"
}상품필터 조회
/campaigns/{campaignId}/product-filter필요 스코프: campaign:read
저장 형식의 차이를 숨기고 ALL, INCLUDE, EXCLUDE 구조로 정규화해 반환합니다. 이 응답의 revision은 상품필터 PATCH·PUT에 사용합니다.
ALL은 모든 상품, INCLUDE는 포함 상품만, EXCLUDE는 지정 상품을 제외한 대상입니다.
여러 그룹을 결합하는 방식입니다.
한 그룹 안의 상품 조건 결합 방식입니다.
빈 배열이면 상품의 모든 옵션, 값이 있으면 해당 옵션만 대상입니다.
curl "https://docs.almani-center.com/open/v1/campaigns/3541/product-filter" \
-H "Authorization: Bearer ak_live_xxxx" \
-H "X-Site-Id: 467"{
"campaignId": 3541,
"revision": "pf_d19b...",
"filter": {
"version": 4,
"mode": "INCLUDE",
"groupJoin": "OR",
"groups": [{
"operator": "OR",
"products": [{
"productId": "27",
"productCode": "P00000BB",
"productName": "다이어리",
"variants": []
}]
}]
}
}상품필터에 상품 추가·제거
/campaigns/{campaignId}/product-filter필요 스코프: campaign:write
ADD_PRODUCTS 또는 REMOVE_PRODUCTS를 지정합니다. 중복 추가는 UNCHANGED로 처리됩니다.
ALL 모드는 부분 변경할 수 없으며 PUT으로 전체 필터를 정의해야 합니다. 마지막 상품 제거도 대상이 전체 상품으로 넓어지는 사고를 막기 위해 거절됩니다.
Request Body
상품 추가 또는 제거 작업입니다.
상품필터 조회 응답의 groups 배열 인덱스입니다. 0부터 시작합니다.
1~100개 상품입니다. productId는 필수이고 variantIds는 최대 500개입니다.
생략하거나 빈 배열이면 상품 전체 옵션입니다. 특정 옵션은 상품 옵션 조회 결과만 사용할 수 있습니다.
상품필터 조회 응답을 다시 사용할 때 지정할 수 있습니다. 각 객체의 variantId만 적용하며 옵션 정보는 서버에서 다시 확인합니다. variantIds와 함께 보내면 두 값이 같아야 합니다.
curl -X PATCH "https://docs.almani-center.com/open/v1/campaigns/3541/product-filter" \
-H "Authorization: Bearer ak_live_xxxx" \
-H "X-Site-Id: 467" \
-H "If-Match: pf_d19b..." \
-H "Idempotency-Key: 79f99cf1-48a3-4f1e-8882-6176b0fae27b" \
-H "Content-Type: application/json" \
-d '{
"operation":"ADD_PRODUCTS",
"groupIndex":0,
"products":[
{"productId":"49","variantIds":[]},
{"productId":"70","variantIds":["P00000XY000A"]}
]
}'{
"campaignId": 3541,
"operation": "ADD_PRODUCTS",
"result": "UPDATED",
"addedProductIds": ["49", "70"],
"removedProductIds": [],
"unchangedProductIds": [],
"summary": {
"mode":"INCLUDE",
"groupCount":1,
"productCount":3,
"variantCount":1
},
"revision": "pf_43c8..."
}상품필터 전체 교체
/campaigns/{campaignId}/product-filter필요 스코프: campaign:write
그룹 구조나 INCLUDE/EXCLUDE 모드를 바꿀 때 사용합니다. mode: ALL은 상품 제한을 제거하므로 명시적인 PUT에서만 허용됩니다.
ALL은 필터를 제거합니다. INCLUDE·EXCLUDE는 하나 이상의 그룹이 필요합니다.
그룹 간 결합 방식이며 생략하면 OR입니다.
최대 20개 그룹입니다. 각 그룹에는 operator와 1~100개의 products가 필요합니다.
products[].variantIds 배열뿐 아니라 상품필터 조회에서 받은 products[].variants 객체 배열도 지원합니다. 두 형식을 함께 지정한 경우 옵션이 다르면 요청을 거절합니다.mode: ALL은 상품 제한을 완전히 제거합니다. 의도한 변경인지 확인한 뒤 실행하고, 적용 후 반드시 다시 조회하세요.curl -X PUT "https://docs.almani-center.com/open/v1/campaigns/3541/product-filter" \
-H "Authorization: Bearer ak_live_xxxx" \
-H "X-Site-Id: 467" \
-H "If-Match: pf_d19b..." \
-H "Idempotency-Key: 18a73926-e9ad-4a87-a750-b3ac84f1c46e" \
-H "Content-Type: application/json" \
-d '{
"mode": "INCLUDE",
"groupJoin": "OR",
"groups": [{
"operator": "OR",
"products": [
{"productId": "27", "variantIds": []},
{"productId": "49", "variantIds": []}
]
}]
}'{
"campaignId": 3541,
"revision": "pf_f605...",
"filter": {
"version": 4,
"mode": "INCLUDE",
"groupJoin": "OR",
"groups": [{
"operator": "OR",
"products": [
{"productId":"27","variants":[]},
{"productId":"49","variants":[]}
]
}]
}
}캠페인 전용 에러
| 코드 | HTTP | 의미 |
|---|---|---|
4000 | 400 | 요청 본문, If-Match 또는 필드 값이 누락·오류. |
4003 | 400 | X-Site-Id 헤더 누락. |
4004 | 403 | API 키 소유자가 아닌 사이트 요청. |
4005 | 403 | campaign:read 또는 campaign:write 스코프 없음. |
4040 | 404 | 사이트에서 캠페인을 찾을 수 없거나 지원 대상 캠페인이 아님. |
4091 | 409 | 같은 사이트의 캠페인 제목 중복 또는 Idempotency-Key 충돌. |
4092 | 409 | revision 불일치. 최신 상태 재조회 필요. |
4220 | 422 | 상품필터, 상품 또는 옵션이 유효하지 않음. |
4221 | 422 | 템플릿이 미승인·비활성 또는 사이트에서 사용할 수 없음. |
4222 | 422 | 플랫폼과 트리거가 일치하지 않거나 발신프로필·템플릿·상품필터 문제로 캠페인을 생성·활성화할 수 없음. |