Open API
콘티플에서 헬프센터 공지사항, FAQ, 티켓 정보 등 다양한 상담 정보를 Open API로 제공합니다.
➊ API 인증 방법
1-1. OPEN API 활성화
[서비스 관리] → [인증]에서 OPEN API를 활성화해주세요.
활성화 시, 서비스 API Key가 자동 생성됩니다.
API를 호출하고 전송되는 데이터를 암호화하는 데에 사용하는 인증키입니다.
API Key 변경 버튼을 클릭하여 변경할 수 있습니다.
1-2. 인증 Header
각 Request Header에 아래의 값들을 반드시 설정해주세요.
Authorization : 암호화 규칙에 따라 생성된 인증 문자열(아래 1-3 참고)
X-TC-Timestamp : 현재 UTC 시간 값 {new Date().getTime()}
Content-Type : application/json; charset=utf-8
1-3. 인증키(Authorization) 생성 방법

① 아래 규칙에 따라 문자열 생성
조직ID(Organization ID)
NHN Cloud 조직 ID로, [전체관리 > 계약 서비스 현황 > 조직정보] 화면에서 확인 가능합니다.
AbcdE1fghIj23K4x와 같은 형태로 구성되어 있습니다.
API URI
호출하려는 API의 URI를 입력합니다. URI에는 서비스ID가 포함되어야 합니다.
예시 :
yourService/openapi/v1/ticket.json
쿼리 파라미터
호출 API에 쿼리 파라미터가 존재할 경우, 키(Key) 알파벳 순서로 정렬한 후 값(Value)을 & 기호로 연결합니다. 파라미터가 1개 일 경우 & 기호는 생략합니다.
예시
쿼리 파라미터가
page=1&pageSize=10&language=ko일 경우,키(Key)의 알파벳 순으로 정렬 :
language=ko&page=1&pageSize=10값(Value)을
&기호로 연결 :ko&1&10
※ 쿼리 파라미터가 없으면 제외
타임 스탬프
API를 요청하는 시간의 Timestamp를 적용합니다. 요청 Header로 전송되는 X-TC-Timestamp 값과 동일해야 합니다.
예시 :
1764031689401
② 문자열 암호화
생성한 문자열을 1-1.Open API 활성화 에서 생성된 API Key로 암호화하여 인증키를 생성합니다.
암호화 방식은 HmacSHA256 방식을 사용합니다.
③ 인증키 전송
인증키를 요청 Header의 Authorization에 적용하여 Contiple로 전송합니다.
Contiple은 전달받은 Header와 Body 변수 값을 동일한 API Key로 암호화하여 Hash 값을 비교합니다.
동일할 경우 API가 정상적으로 처리되며, 일치하지 않을 경우 오류코드 400을 반환합니다.
1-4. JAVA 예제
(1) 일반 요청(GET)
// 유저 티켓 리스트
String URL = "http://yourOrg.oc.nhncloud.com/yourService/openapi/v1/ticket/enduser/usercode/list.json?categoryId=1&language=ko";
String organizationId = "AbcdE1fghIj23K4x"; // OrganizationID
String securityKey = "123456a0bcde12a789b123bc4d1234a1"; // Service API Key
String uri = "/yourService/openapi/v1/ticket/enduser/usercode/list.json"; // Request URI
long timestamp = new Date().getTime();
StringBuilder sb = new StringBuilder();
sb.append(organizationId);
sb.append(uri);
sb.append("1").append("&").append("ko"); // 매개변수 이름의 알파벳 순서에 따라 &기호로 값 연결, 없으면 생략
sb.append(timestamp);// X-TC-Timestamp값과 동일
SecretKeySpec signingKey = new SecretKeySpec(securityKey.getBytes("UTF-8"), "HmacSHA256");
Mac mac = Mac.getInstance(signingKey.getAlgorithm());
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(sb.toString().getBytes("UTF-8"));
String authorization = new String(Base64.encodeBase64(rawHmac));
Request request = new Request.Builder().url(URL).get()
.header("Content-Type", "application/json")
.header("Authorization", authorization)
.header("X-TC-Timestamp", Long.toString(timestamp))
.build();
Call call = client.newCall(request);
Response response = call.execute();(2) 일반 요청(POST)
// 티켓 생성
String URL = "http://yourOrg.oc.nhncloud.com/yourService/openapi/v1/ticket.json?language=ko";
String organizationId = "AbcdE1fghIj23K4x"; // OrganizationID
String securityKey = "123456a0bcde12a789b123bc4d1234a1"; // Service API Key
String uri = "/yourService/openapi/v1/ticket.json"; // Request URI
long timestamp = new Date().getTime();
StringBuilder sb = new StringBuilder();
String body = mapper.writeValueAsString(bodyContentObject);
sb.append(organizationId);
sb.append(uri);
sb.append("ko").append("&"); // 매개변수 이름의 알파벳 순서에 따라 &기호로 값 연결, 없으면 생략
sb.append(body);// 매개변수 뒤에 body의 문자열 내용 추가
sb.append(timestamp);// X-TC-Timestamp값과 동일
SecretKeySpec signingKey = new SecretKeySpec(securityKey.getBytes("UTF-8"), "HmacSHA256");
Mac mac = Mac.getInstance(signingKey.getAlgorithm());
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(sb.toString().getBytes("UTF-8"));
String authorization = new String(Base64.encodeBase64(rawHmac));
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), body);
Request request = new Request.Builder().url(URL).post(body)
.header("Content-Type", "application/json")
.header("Authorization", authorization)
.header("X-TC-Timestamp", Long.toString(timestamp))
.header("OC-Client-IP", ip)
.build();
Call call = client.newCall(request);
Response response = call.execute();(3) 파일 업로드
String URL = "http://yourOrg.oc.nhncloud.com/yourService/openapi/v1/ticket/attachments/upload.json";
String organizationId = "AbcdE1fghIj23K4x"; // OrganizationID
String securityKey = "123456a0bcde12a789b123bc4d1234a1"; // Service API Key
String uri = "/yourService/openapi/v1/ticket/attachments/upload.json"; // Request URI
StringBuilder sb = new StringBuilder();
sb.append(organizationId);
sb.append(uri);
DigestUtils.appendMd5DigestAsHex(file.getInputStream(), sb);// 파일 첨부 시 파일의 MD5는 파라미터 값으로 인증 문자열에 추가
sb.append(new Date().getTime());// X-TC-Timestamp값과 동일
SecretKeySpec signingKey = new SecretKeySpec(securityKey.getBytes("UTF-8"), "HmacSHA256");
Mac mac = Mac.getInstance(signingKey.getAlgorithm());
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(sb.toString().getBytes("UTF-8"));
String authorization = new String(Base64.encodeBase64(rawHmac));(3) 콘티플 측 인증 방법
// Generate authorization string sample with request
StringBuilder sb = new StringBuilder();
sb.append(org.getId()); // organization Id
sb.append(request.getRequestURI()); // request URI
// upload file
if (request instanceof MultipartHttpServletRequest) {
MultipartHttpServletRequest mpRequest = (MultipartHttpServletRequest) request;
MultipartFile file = mpRequest.getFile("file");
DigestUtils.appendMd5DigestAsHex(file.getInputStream(), sb);
// other
} else {
Map<String, String[]> params = request.getParameterMap();
if (!params.isEmpty()) {
// Sort parameter
Map<String, String[]> treeMap = new TreeMap<>(params);
for (Map.Entry<String, String[]> entry : treeMap.entrySet()) {
sb.append(entry.getValue()[0]).append("&");
}
sb.deleteCharAt(sb.length() - 1); // Delete '&' character
}
if (request instanceof BodyReaderHttpServletRequestWrapper) {
BodyReaderHttpServletRequestWrapper requestWrapper = (BodyReaderHttpServletRequestWrapper) request;
if (requestWrapper.hasBody()) {
String body = new String(requestWrapper.getBody(), StandardCharsets.UTF_8);
if (!params.isEmpty()) {
// params is not empty, add '&' character
sb.append("&");
}
sb.append(body);
}
}
}
String time = request.getHeader("X-TC-Timestamp");
// No '&' character
sb.append(time);
return sb.toString();콘티플 인증 실패 시, 결과는 아래와 같이 반환됩니다. (Authorization 문자열의 암호화 방식이 올바른지 확인해주세요.)
{
"header": {
"resultCode": 400,
"resultMessage": "무효한 요청입니다.",
"isSuccessful": false
},
"result": null
}인증 실패 상황
400
Authorization is blank
X-TC-Timestamp is not numeric
X-TC-Timestamp is expired (5분 내 유효)
Multipart request but file is null
Authorization is incorrect
403
securityKey is null
clientIp is not allowed
➋ 공통 리턴 결과
2-1. 리턴 결과 예제
//성공: 상세
{
"header": {
"resultCode": 200,
"resultMessage": "",
"isSuccessful": true
},
"result": {
"content": {
}
}
}
//성공: 리스트
{
"header": {
"resultCode": 200,
"resultMessage": "",
"isSuccessful": true
},
"result": {
"contents": [{
}]
}
}
//실패
{
"header": {
"resultCode": 403,
"resultMessage": "Access Denied",
"isSuccessful": false
},
"result": null
}2-2. 리턴 결과 설명
Header
resultCode
Integer
리턴 결과 Code, 정상은 200
resultMessage
String
리턴 오류 메시지
isSuccessful
Boolean
실행 결과(성공: true, 실패: false)
Result
contents
JSON
목록 결과 내용
content
JSON
상세 결과 내용
2-3. 리턴 코드
200 : SUCCESS
400 : Bad Request
403 : Access Denied(Forbidden)
404 : Not Data Found
500 : Server Error
9007 : 관련된 데이터가 이미 존재
9005 : 관련된 데이터가 없음
1001 : 문의 횟수가 상한을 초과했습니다. 잠시 후 문의해주세요.
[스팸 관리] → [반복 문의 차단] 기능 사용 시 작동
동일 IP로 1분 내에 3번 이상 문의 생성 시도 시, 24시간 동안 티켓 생성 차단
1002 : 문의 횟수가 상한을 초과했습니다. 잠시 후 문의해주세요.
[스팸 관리] → [반복 문의 차단] 기능 사용 시 작동
동일 IP로 24시간 내에 10번 이상 문의 생성 시도 시, 24시간 동안 티켓 생성 차단
2-4. 리턴 코드(실패) 상세
400
Authorization is blank
X-TC-Timestamp is not numeric
X-TC-Timestamp is expired (5분 내 유효)
Multipart request but file is null
Authorization is incorrect
403
securityKey is null
clientIp is not allowed
➌ API 목록
3-1. 개발 환경 URL
알파
https://{domain}.oc.alpha-nhncloud.com
베타
https://{domain}.oc.beta-nhncloud.com
리얼
https://{domain}.oc.nhncloud.com
3-2. Security Key URL
서비스의 Security Key
/{serviceId}/openapi/v1/*
인증 없이 직접 사용 가능
/{serviceId}/api/v2/*
3-3. API 목록
서비스
서비스 상세
GET
/{serviceId}/api/v2/service.json
서비스 ID를 통해 서비스 정보 조회
공지사항
말머리 리스트
GET
/{serviceId}/api/v2/notice/categories.json
공지사항 말머리 리스트 취득
태그 리스트
GET
/{serviceId}/api/v2/notice/tags.json
공지사항 태그 리스트 취득
공지사항 리스트
GET
/{serviceId}/api/v2/notice/list.json
헬프센터 공지사항 리스트
공지사항 상세
GET
/{serviceId}/api/v2/notice/detail/{id}.json
공지사항 ID를 통해 공지사항 내용 취득
공지사항 첨부파일 열기 및 다운로드
GET
/{serviceId}/api/v2/notice/attachments/{id}
공지사항 첨부파일 열기/다운로드
FAQ
카테고리 리스트
GET
/{serviceId}/api/v2/helpdoc/categories.json
FAQ 카테고리 리스트 취득
FAQ 리스트
GET
/{serviceId}/api/v2/helpdoc/list.json
헬프센터 FAQ 리스트
FAQ 상세
GET
/{serviceId}/api/v2/helpdoc/detail/{id}.json
FAQ ID를 통해 FAQ 내용 취득
FAQ 첨부파일 열기 및 다운로드
GET
/{serviceId}/api/v2/helpdoc/attachments/{id}
FAQ 첨부파일 열기 및 다운로드
문의 접수
접수유형 리스트
GET
/{serviceId}/api/v2/ticket/categories.json
서비스 내 접수유형 리스트 조회
접수유형 필드 리스트
GET
/{serviceId}/api/v2/ticket/field/user/{categoryId}.json
접수유형을 통하여 대응되는 필드 리스트 확인
티켓 첨부파일 업로드
POST
/{serviceId}/openapi/v1/ticket/attachments/upload.json
서버에 파일 업로드
티켓 생성
POST
/{serviceId}/openapi/v1/ticket.json
신규 티켓 생성
문의 내역
고객 티켓 리스트
GET
/{serviceId}/openapi/v1/ticket/enduser/{usercode}/list.json
검색 조건을 통해 조건에 맞는 고객의 티켓 리스트 노출
티켓 상세
GET
/{serviceId}/openapi/v1/ticket/enduser/{usercode}/{ticketId}/detail.json
고객이 접수한 티켓 상세 조회
티켓 첨부파일 열기 및 다운로드
GET
/{serviceId}/api/v2/ticket/attachments/{id}
티켓 첨부파일 열기/다운로드
고객 재문의
POST
/{serviceId}/openapi/v1/ticket/enduser/{usercode}/{ticketId}/comment.json
티켓 ID 기준으로 고객 재문의
Last updated