URL줄이기 개발자 API

개발자 API 소개

비볼디는 귀사의 플랫폼 또는 시스템을 위해 전용 REST API를 제공합니다.
REST API를 이용하면 비볼디 대시보드에서 링크를 만들지 않고도 귀하가 소유하고 있는 서버 또는 모바일 앱에서 자유롭게 링크를 만들 수 있습니다.

제공되는 REST API는 JavaScript, PHP, Java, Android, iOS 등 개발 언어와 운영체제에 상관없이 자유롭게 API를 호출할 수 있습니다.
API를 호출하기 전 반드시 API Key가 생성되어 있어야 하며 생성된 API Key는 타인에게 노출되지 않도록 관리가 필요합니다.

API Key 변경은 1달 마다 가능하며 API Key가 변경되어도 이미 생성된 링크에는 아무런 영향이 없습니다.
모든 API는 무료 요금제도 얼마든지 이용할 수 있고 비볼디에서 정한 Request 규격에 따르며, 요금제에 따라 API 처리와 응답 속도가 다릅니다.

API 호출 후 HTTP 403 오류가 발생하면, Header에 별도의 User-agent 값을 지정하세요.
비볼디는 악성 봇과 크롤러를 차단하고 있으며, 내부적으로 블랙리스트 IP 대역을 관리하고 있습니다.
안전하게 API를 호출하려면 User-agent 값에 비볼디가 인식할 수 있는 귀하의 회사명 또는 브랜드명을 영문으로 설정하세요.

비볼디에서 기능 변경과 추가로 인한 운영서버 배포 그리고 보안 패치로 인한 서버 재부팅 중 API가 호출되면 호출에 실패할 수 있으므로 API 재호출 로직을 구현하는 것을 권장합니다.

단축url, url단축, 링크줄이기를 위한 개발자 REST API

API 호출 방법

Request:
Host: https://vivoldi.com/api HTTP/1.1
Authorization: APIKey {Your API Key}
Content-type: application/json
Authorization, Content-type을 Http Header에 추가한 후 API를 호출하면 됩니다.
응답 메시지가 영어로 표시되는 경우, header에 “Accept-Language: ko”로 설정하세요.
Response:
{
    "code": 0,
    "message": "",
    "result": Object
}
code - 응답 코드로 0은 성공이며 이외 값은 실패 코드입니다.
message - 응답 메시지로 응답 코드가 0이 아닌 경우 오류 메시지가 리턴됩니다.
result - 응답 값으로 API 유형에 따라 문자 또는 JSON Object로 리턴됩니다.
REST API 개선 또는 수정이 필요할 경우 비볼디에 문의주세요.

링크 생성

1개의 단축 링크를 생성합니다. 만약, 한번에 여러 개의 링크를 만들고자 한다면 “링크 일괄 생성” API를 이용하세요.
한번에 대량의 링크를 만들고자 한다면, 대시보드의 “대량 링크 만들기” 메뉴를 이용하세요.
무료 요금제는 1분당 최대 10번의 API 호출로 제한됩니다.

Request:
Post /api/link/v2/create HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/json
Request:
필드 필드 설명 설명 필수 유형
url 긴 URL 생성된 짧은 링크를 클릭했을 때 이동될 긴 URL.
최대 3,000 bytes까지 설정할 수 있습니다.
string
domain 도메인 값이 비어 있으면 자동으로 vvd.bz 도메인으로 설정됩니다.
“https://” 값을 포함하여 설정해야 하며, “brandLinkId” 옵션이 “Y”일 경우 도메인은 “https://vvd.im”으로 설정하세요.
귀하가 소유한 도메인을 비볼디와 연동하였을 경우 해당 도메인을 설정하면 됩니다.
예: https://vvd.bz
string
redirectType Redirect 방법 짧은 URL에서 긴 URL로 이동되는 방식을 설정합니다.
HTTP의 상태 응답 코드로 200, 301, 302 중에 하나를 선택할 수 있습니다. 기본 값: 302
Redirect 방법에 대한 자세한 내용는 “용어 정리” 페이지에서 확인하세요.
int
grpIdx 그룹ID 그룹ID를 설정하면 해당 그룹에 링크가 생성됩니다.
그룹ID를 확인하려면 "그룹 목록" API를 호출하여 확인해야 합니다.
int
brandLinkId 브랜드 링크ID 값을 지정하면 해당 ID로 링크가 생성됩니다.
(브랜드 링크가 설정된 경우 도메은 vvd.bz이 아닌 vvd.im 입니다)
값이 비어 있으면 링크ID는 자동으로 생성됩니다.
string
ttl 링크 제목 값이 비어 있으면 긴 URL의 웹페이지 제목으로 저장됩니다.
값이 비어있을 때, 긴 URL에 접속하여 HTML 파싱 작업이 이루어 지므로 API 호출 후 응답 속도가 느리다면 제목을 설정하세요.
string
description Meta 내용 “redirectType”의 값이 “200”일 때 페이지의 메타 태그인 description을 설정할 수 있습니다.
“redirectType”의 값이 “301”, “302”일 때는 이 값은 무시됩니다.
string
memo 메모 사용자에게 노출되지 않고 관리에 필요한 부가 정보를 설정할 수 있습니다. string
notfSubscYn 푸시구독 링크 값이 Y일 경우 생성된 링크를 클릭하면 긴 링크로 이동되기 전 웹푸시 알림 팝업이 표시되고
사용자가 푸시알림에 허용할 경우 허용한 모든 사용자들에게 푸시 메시지를 전송할 수 있습니다.
알림 팝업에 동의하지 않거나 취소할 경우 즉시 원래의 긴 URL로 이동됩니다.
값을 입력하지 않으면 기본 값은 N 입니다.
푸시구독 링크에 대해 자세히 알아보시려면 웹푸시 기능 소개 페이지에서 살펴보세요.
Y or N
blockOverseasSticsYn 해외통계 차단 값이 Y일 경우 한국 이외 국가에서 링크를 클릭할 경우 링크 접속은 가능하지만 클릭 수 통계를 저장하지 않습니다.
악성 봇 또는 검색 로봇으로 인해 클릭 수가 비정상적으로 많을 경우 값을 Y로 설정하세요.
Y or N
clksIpFilteringYn 클릭 수 IP 필터링 값이 Y일 경우 최근 3일 동안 동일 IP에서 링크를 클릭할 때 링크 클릭 수가 계속 증가하지 않고 1로 고정됩니다.
3일이 지나고 4일재 되는 날 부터 다시 링크를 클릭하면 클릭 수가 +1 됩니다.
클릭 수 IP 필터링 기능은 링크 생성 시에만 설정이 가능하며 이후 링크 수정으로 값을 변경할 수 없습니다.
이 기능은 퍼스널 요금제부터 이용할 수 있습니다.
Y or N
pushNotifyYn 클릭 수 푸시 알림 값이 Y일 경우 "설정 -> 환경 설정" 페이지의 링크 설정에서 설정된 링크 클릭 수에 도달할 때 마다 비볼디 앱이 설치된 모바일 기기로 클릭 수 푸시 알림을 수신할 수 있습니다.
이 기능은 퍼스널 요금제부터 이용할 수 있습니다.
Y or N
mailNotifyYn 클릭 수 메일 알림 값이 Y일 경우 "설정 -> 환경 설정" 페이지의 링크 설정에서 설정된 링크 클릭 수에 도달할 때 마다 비볼디에 가입된 이메일로 클릭 수 정보를 수신할 수 있습니다.
이 기능은 퍼스널 요금제부터 이용할 수 있습니다.
Y or N
delYmd 링크 삭제 날짜 설정된 날짜가 지나면 링크가 시스템에 의해 자동으로 삭제됩니다.
삭제 주기: 1시간 마다
예: 2025-12-31
Date
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnCreateLink" type="button">Create Link</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnCreateLink").on('click', function(evt){
		evt.preventDefault();

		$.ajax({
			type: 'POST',
			url: 'https://vivoldi.com/api/link/v2/create',
			data: JSON.stringify({'url':'https://google.com','domain':'https://vvd.bz'}),
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			contentType: 'application/json; charset=utf-8',
			dataType: 'json',
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				alert('short url: ' + res.result);
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$url = "https://vivoldi.com/api/link/v2/create";
$params = array (
	"url" => "https://www.facebook.com/vivoldi365",
	"domain" => "https://vvd.bz",
);
$body = json_encode($params);

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX",
	"Content-Type: application/json"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class CreateLink {
    public static void main(String[] args) {
        try (HttpClient client = HttpClient.newBuilder().build()) {
            JSONObject params = new JSONObject();
            params.put("url", "https://www.facebook.com/vivoldi365");
            params.put("domain", "https://vvd.bz");

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/link/v2/create"))
                .header("Content-Type", "application/json")
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .POST(HttpRequest.BodyPublishers.ofString(params.toString()))
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println("Short URL: " + json.getString("result"));
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
    }
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result":"https://vvd.bz/jH3d"
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string
result 응답 값 (단축된 링크) string

링크 일괄 생성

한번에 여러 개의 단축 링크를 생성합니다.
한번에 대량의 링크를 만들고자 한다면, 대시보드의 “대량 링크 만들기” 메뉴를 이용하세요.

한번에 생성 가능한 링크 개수는 제한되어 있으며 요금제별 제한은 아래와 같습니다.
만약, 3,000개의 링크를 생성하고자 한다면 본 API를 여러 번 호출해야 합니다.

퍼스널 요금제: 최대 200개
프리미엄 요금제: 최대 500개
비즈니스 요금제: 최대 1,000개

본 API는 퍼스널 요금제부터 사용할 수 있습니다.

Request:
Post /api/link/v1/createBulk HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/json
Request:
필드 유형
links
필드 필드 설명 설명 필수 유형
url 긴 URL 생성된 짧은 링크를 클릭했을 때 이동될 긴 URL.
최대 3,000 bytes까지 설정할 수 있습니다.
string
domain 도메인 값이 비어 있으면 자동으로 vvd.bz 도메인으로 설정됩니다.
“https://” 값을 포함하여 설정해야 하며, “brandLinkId” 옵션이 “Y”일 경우 도메인은 “https://vvd.im”으로 설정하세요.
귀하가 소유한 도메인을 비볼디와 연동하였을 경우 해당 도메인을 설정하면 됩니다.
예: https://vvd.bz
string
redirectType Redirect 방법 짧은 URL에서 긴 URL로 이동되는 방식을 설정합니다.
HTTP의 상태 응답 코드로 200, 301, 302 중에 하나를 선택할 수 있습니다. 기본 값: 302
Redirect 방법에 대한 자세한 내용는 “용어 정리” 페이지에서 확인하세요.
int
grpIdx 그룹ID 그룹ID를 설정하면 해당 그룹에 링크가 생성됩니다.
그룹ID를 확인하려면 "그룹 목록" API를 호출하여 확인해야 합니다.
int
brandLinkId 브랜드 링크ID 값을 지정하면 해당 ID로 링크가 생성됩니다.
(브랜드 링크가 설정된 경우 도메은 vvd.bz이 아닌 vvd.im 입니다)
값이 비어 있으면 링크ID는 자동으로 생성됩니다.
string
ttl 링크 제목 값이 비어 있으면 긴 URL의 웹페이지 제목으로 저장됩니다.
값이 비어있을 때, 긴 URL에 접속하여 HTML 파싱 작업이 이루어 지므로 API 호출 후 응답 속도가 느리다면 제목을 설정하세요.
string
description Meta 내용 “redirectType”의 값이 “200”일 때 페이지의 메타 태그인 description을 설정할 수 있습니다.
“redirectType”의 값이 “301”, “302”일 때는 이 값은 무시됩니다.
string
memo 메모 사용자에게 노출되지 않고 관리에 필요한 부가 정보를 설정할 수 있습니다. string
notfSubscYn 푸시구독 링크 값이 Y일 경우 생성된 링크를 클릭하면 긴 링크로 이동되기 전 웹푸시 알림 팝업이 표시되고
사용자가 푸시알림에 허용할 경우 허용한 모든 사용자들에게 푸시 메시지를 전송할 수 있습니다.
알림 팝업에 동의하지 않거나 취소할 경우 즉시 원래의 긴 URL로 이동됩니다.
값을 입력하지 않으면 기본 값은 N 입니다.
푸시구독 링크에 대해 자세히 알아보시려면 웹푸시 기능 소개 페이지에서 살펴보세요.
Y or N
blockOverseasSticsYn 해외통계 차단 값이 Y일 경우 한국 이외 국가에서 링크를 클릭할 경우 링크 접속은 가능하지만 클릭 수 통계를 저장하지 않습니다.
악성 봇 또는 검색 로봇으로 인해 클릭 수가 비정상적으로 많을 경우 값을 Y로 설정하세요.
Y or N
clksIpFilteringYn 클릭 수 IP 필터링 값이 Y일 경우 최근 3일 동안 동일 IP에서 링크를 클릭할 때 링크 클릭 수가 계속 증가하지 않고 1로 고정됩니다.
3일이 지나고 4일재 되는 날 부터 다시 링크를 클릭하면 클릭 수가 +1 됩니다.
클릭 수 IP 필터링 기능은 링크 생성 시에만 설정이 가능하며 이후 링크 수정으로 값을 변경할 수 없습니다.
이 기능은 퍼스널 요금제부터 이용할 수 있습니다.
Y or N
pushNotifyYn 클릭 수 푸시 알림 값이 Y일 경우 "설정 -> 환경 설정" 페이지의 링크 설정에서 설정된 링크 클릭 수에 도달할 때 마다 비볼디 앱이 설치된 모바일 기기로 클릭 수 푸시 알림을 수신할 수 있습니다.
이 기능은 퍼스널 요금제부터 이용할 수 있습니다.
Y or N
mailNotifyYn 클릭 수 메일 알림 값이 Y일 경우 "설정 -> 환경 설정" 페이지의 링크 설정에서 설정된 링크 클릭 수에 도달할 때 마다 비볼디에 가입된 이메일로 클릭 수 정보를 수신할 수 있습니다.
이 기능은 퍼스널 요금제부터 이용할 수 있습니다.
Y or N
delYmd 링크 삭제 날짜 설정된 날짜가 지나면 링크가 시스템에 의해 자동으로 삭제됩니다.
삭제 주기: 1시간 마다
예: 2025-12-31
Date
array
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnCreateBulkLinks" type="button">Create bulk links</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnCreateBulkLinks").on('click', function(evt){
		evt.preventDefault();
		const params = {
			'links': [
				{'url':'https://google.com','domain':'https://vvd.bz'},
				{'url':'https://facebook.com','domain':'https://vvd.bz'},
				{'url':'https://twitter.com','domain':'https://vvd.bz'}
			]
		};
		$.ajax({
			type: 'POST',
			url: 'https://vivoldi.com/api/link/v1/createBulk',
			data: JSON.stringify(params),
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			contentType: 'application/json; charset=utf-8',
			dataType: 'json',
			timeout: 10000
		}).done(function(res){
			if (res.code === 0) {
				console.log(res.result);
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$url = "https://vivoldi.com/api/link/v1/createBulk";
$params = array (
	"links" => array(
		array(
			"url" => "https://google.com",
			"domain" => "https://vvd.bz"
		),
		array(
			"url" => "https://facebook.com",
			"domain" => "https://vvd.bz"
		),
		array(
			"url" => "https://twitter.com",
			"domain" => "https://vvd.bz"
		)
	)
);
$body = json_encode($params);

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX",
	"Content-Type: application/json"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.json.JSONArray;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class CreateLink {
    public static void main(String[] args) {
        try (HttpClient client = HttpClient.newBuilder().build()) {
			JSONObject link1 = new JSONObject();
			link1.put("url", "https://google.com").put("domain", "https://vvd.bz");

			JSONObject link2 = new JSONObject();
			link2.put("url", "https://facebook.com").put("domain", "https://vvd.bz");

			JSONObject link3 = new JSONObject();
			link3.put("url", "https://twitter.com").put("domain", "https://vvd.bz");

			JSONArray links = new JSONArray();
			links.put(link1);
			links.put(link2);
			links.put(link3);

            JSONObject params = new JSONObject();
            params.put("links", links);

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/link/v2/create"))
                .header("Content-Type", "application/json")
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .POST(HttpRequest.BodyPublishers.ofString(params.toString()))
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println("Short URL: " + json.getString("result"));
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
    }
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result":[
        {shortUrl: "https://vvd.bz/bbuR", url: "https://google.com"},
        {shortUrl: "https://vvd.bz/bbuS", url: "https://facebook.com"},
        {shortUrl: "https://vvd.bz/bbuT", url: "https://twitter.com"}
    ]
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string
result 응답 값 (단축된 링크) string

링크 수정

생성한 짧은 링크를 수정합니다.
링크 유형이 URL인 경우만 수정할 수 있으며 이외 유형은 API 호출에 성공하여도 수정되지 않습니다.

Request:
Put /api/link/v2/edit HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/json
Request:
필드 필드 설명 설명 필수 유형
linkId 링크ID 생성된 짧은 링크의 ID
예:
짧은 링크의 주소가 "https://vvd.bz/fML"이면 링크ID는 fML 입니다.
string
domain 도메인 짧은 링크 주소의 도메인.
예:
짧은 링크의 주소가 "https://vvd.bz/fML"이면 도메인은 https://vvd.bz 입니다.
중요: https:// 또는 http:// 값을 반드시 입력해야 합니다.
생성된 짧은 링크의 도메인이 아닌 다른 도메인으로 설정할 경우 오류가 발생합니다.
string
redirectType Redirect 방법 짧은 URL에서 긴 URL로 이동되는 방식을 설정합니다.
HTTP의 상태 응답 코드로 200, 301, 302 중에 하나를 선택할 수 있습니다. 기본 값: 302
Redirect 방법에 대한 자세한 내용는 “용어 정리” 페이지에서 확인하세요.
int
grpIdx 그룹ID 생성된 링크의 그룹을 변경합니다.
그룹ID를 확인하려면 "그룹 목록" API를 호출하여 확인해야 합니다.
int
url 긴 URL 긴 URL을 변경합니다.
프리미엄 요금제부터 긴 URL을 변경할 수 있습니다.
string
ttl 링크 제목 값이 비어 있으면 링크 제목이 수정되지 않습니다.
string
description Meta 내용 “redirectType”의 값이 “200”일 때 페이지의 메타 태그인 description을 설정할 수 있습니다.
“redirectType”의 값이 “301”, “302”일 때는 이 값은 무시됩니다.
string
memo 메모 사용자에게 노출되지 않고 관리에 필요한 부가 정보를 설정할 수 있습니다.
값이 비어 있으면 메모가 수정되지 않습니다.
string
notfSubscYn 푸시구독 링크 값이 Y일 경우 생성된 링크를 클릭하면 긴 링크로 이동되기 전 웹푸시 알림 팝업이 표시되고
사용자가 푸시알림에 허용할 경우 허용한 모든 사용자들에게 푸시 메시지를 전송할 수 있습니다.
알림 팝업에 동의하지 않거나 취소할 경우 즉시 원래의 긴 URL로 이동됩니다.
값을 입력하지 않으면 기본 값은 N 입니다.
푸시구독 링크에 대해 자세히 알아보시려면 여기를 클릭하세요.
Y or N
blockOverseasSticsYn 해외통계 차단 값이 Y일 경우 한국 이외 국가에서 링크를 클릭할 경우 링크 접속은 가능하지만 클릭 수 통계를 저장하지 않습니다.
악성 봇 또는 검색 로봇으로 인해 클릭 수가 비정상적으로 많을 경우 값을 Y로 설정하세요.
Y or N
pushNotifyYn 클릭 수 푸시 알림 값이 Y일 경우 "설정 -> 환경 설정" 페이지의 링크 설정에서 설정된 링크 클릭 수에 도달할 때 마다 비볼디 앱이 설치된 모바일 기기로 클릭 수 푸시 알림을 수신할 수 있습니다.
이 기능은 퍼스널 요금제부터 이용할 수 있습니다.
Y or N
mailNotifyYn 클릭 수 메일 알림 값이 Y일 경우 "설정 -> 환경 설정" 페이지의 링크 설정에서 설정된 링크 클릭 수에 도달할 때 마다 비볼디에 가입된 이메일로 클릭 수 정보를 수신할 수 있습니다.
이 기능은 퍼스널 요금제부터 이용할 수 있습니다.
Y or N
delYmd 링크 삭제 날짜 설정된 날짜가 지나면 링크가 시스템에 의해 자동으로 삭제됩니다.
삭제 주기: 1시간 마다
예: 2025-12-31
Date
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnUpdateLink" type="button">Update Link</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnUpdateLink").on('click', function(evt){
		evt.preventDefault();

		$.ajax({
			type: 'PUT',
			url: 'https://vivoldi.com/api/link/v2/edit',
			data: JSON.stringify({'linkId':'jH3d','domain':'https://vvd.bz','ttl':'new title','memo':'new my memo'}),
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			contentType: 'application/json; charset=utf-8',
			dataType: 'json',
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				alert('Success!');
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$url = "https://vivoldi.com/api/link/v2/edit";
$params = array (
	"linkId" => "4Rt3",
	"domain" => "https://vvd.bz",
	"ttl" => "new title",
	"memo" => "new my memo"
);
$body = json_encode($params);

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX",
	"Content-Type: application/json"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class UpdateLink {
	public static void main(String[] args) {
		try (HttpClient client = HttpClient.newBuilder().build()) {
            JSONObject params = new JSONObject();
            params.put("linkId", "jH3d");
            params.put("domain", "https://vvd.bz");
			params.put("ttl", "new title");
			params.put("memo", "new my memo");

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/link/v2/edit"))
                .header("Content-Type", "application/json")
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .PUT(HttpRequest.BodyPublishers.ofString(params.toString()))
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println("success!");
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":""
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string

링크 삭제

생성한 짧은 링크를 삭제합니다.

Request:
Delete /api/link/v1/remove HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: -
Request:
필드 필드 설명 설명 필수 유형
linkId 링크 ID 생성된 짧은 링크의 ID
예:
짧은 링크의 주소가 "https://vvd.bz/fML"이면 링크ID는 fML 입니다.
브랜드 링크ID(링크ID를 직접 설정)가 설정되어 있고 특수문자가 포함되어 있으면 URLEncode가 필요합니다.
string
domain 도메인 짧은 링크 주소의 도메인.
예:
짧은 링크의 주소가 "https://vvd.bz/fML"이면 도메인은 https://vvd.bz 입니다.
중요: https:// 또는 http:// 값을 반드시 입력해야 합니다.
생성된 짧은 링크의 도메인이 아닌 다른 도메인으로 설정할 경우 오류가 발생합니다.
브랜드 링크ID(링크ID를 직접 설정)의 경우 도메인은 https://vvd.im 입니다.
string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnDeleteLink" type="button">Delete Link</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnDeleteLink").on('click', function(evt){
		evt.preventDefault();

		$.ajax({
			type: 'DELETE',
			url: 'https://vivoldi.com/api/link/v1/remove?linkId=강남스타벅스점&domain=https://vvd.im',
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				alert('Success!');
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$linkId = urlencode("강남스타벅스점");
$url = "https://vivoldi.com/api/link/v1/remove?linkId=$linkId&domain=https://vvd.im";

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class DeleteLink {
	public static void main(String[] args) {
		try (HttpClient client = HttpClient.newBuilder().build()) {
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/link/v1/remove?linkId=강남스타벅스점&domain=https://vvd.im"))
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .DELETE()
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println("success!");
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":""
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string

시간대별 클릭 수 통계

링크 1개의 특정 날짜애 대한 시간대별 클릭 수, 클릭 사람 수를 조회할 수 있습니다.

본 API는 비즈니스 요금제부터 사용할 수 있습니다.

Request:
Get /api/statistics/v1/clicks-by-time HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: -
Request:
필드 필드 설명 설명 필수 유형
linkId 링크 ID 링크 ID로 통계를 조회합니다.
브랜드 링크(링크ID를 직접 설정)로 설정된 링크 중 특수문자가 포함되어 있으면 URLEncode가 필요합니다.
string
domain 도메인 링크 도메인으로 목록을 조회합니다.
도메인 앞에 반드시 http:// 또는 https:// 값을 붙여야 합니다.
브랜드 링크(링크ID를 직접 설정)가 설정되어 있는 경우 도메인은 https://vvd.bz이 아닌 https://vvd.im 입니다.
string
ymd 날짜 해당 날짜의 시간대별 클릭 수와 클릭 사람 수 목록을 조회합니다.
오늘로 부터 최대 7일 전 날짜만 입력할 수 있습니다.
예: 2024-06-14
string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnClickList" type="button">Get click list</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnClickList").on('click', function(evt){
		evt.preventDefault();

		const linkId = 'y6Tg';
		const domain = 'https://vvd.bz';
		const ymd = '2024-06-14';

		$.ajax({
			type: 'GET',
			url: 'https://vivoldi.com/api/statistics/v1/clicks-by-time?linkId='+linkId+'&domain='+domain+'&ymd='+ymd,
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				console.log(res);
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$linkId = "y6Tg";
$domain = "https://vvd.bz";
$ymd = "2024-06-14";
$url = "https://vivoldi.com/api/statistics/v1/clicks-by-time?linkId=$linkId&domain=$domain&ymd=$ymd";

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ClickList {
	public static void main(String[] args) {
		try (HttpClient client = HttpClient.newBuilder().build()) {
            String nm = URLEncoder.encode("my test group", StandardCharsets.UTF_8);
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/statistics/v1/clicks-by-time?linkId=y6Tg&domain=https://vvd.bz&ymd=2024-06-14"))
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .GET()
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println(json.getString("result"));
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result":[
        {
            "ymd":"2024-06-14",
            "hour":"00",
            "linkId":"y6Tg",
            "domain":"https://vvd.bz",
            "acesCnt":24,
            "pernCnt":17,
        },
        {
            "ymd":"2024-06-14",
            "hour":"08",
            "linkId":"y6Tg",
            "domain":"https://vvd.bz",
            "acesCnt":121,
            "pernCnt":198,
        }
        {
            "ymd":"2024-06-14",
            "hour":"14",
            "linkId":"y6Tg",
            "domain":"https://vvd.bz",
            "acesCnt":84,
            "pernCnt":68,
        }
    ]
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string
result 통계 목록:
필드 필드 설명 설명 유형
ymd 날짜 - string
hour 시간 00시 ~ 23시 string
linkId 링크 ID - string
domain 도메인 - string
acesCnt 클릭 수 링크 클릭 수 int
pernCnt 클릭 사람 수 링크를 클릭한 사람 수 int
array

날짜별 클릭 수 통계

링크 1개에 대한 날짜별 클릭 수, 클릭 사람 수를 조회할 수 있습니다.
검색할 때 시작 날짜와 종료 날짜의 범위는 1달을 넘을 수 없습니다.

본 API는 비즈니스 요금제부터 사용할 수 있습니다.

Request:
Get /api/statistics/v1/clicks-by-date HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: -
Request:
필드 필드 설명 설명 필수 유형
linkId 링크 ID 링크 ID로 통계를 조회합니다.
브랜드 링크(링크ID를 직접 설정)로 설정된 링크 중 특수문자가 포함되어 있으면 URLEncode가 필요합니다.
string
domain 도메인 링크 도메인으로 목록을 조회합니다.
도메인 앞에 반드시 http:// 또는 https:// 값을 붙여야 합니다.
브랜드 링크(링크ID를 직접 설정)가 설정되어 있는 경우 도메인은 https://vvd.bz이 아닌 https://vvd.im 입니다.
string
startYmd 시작 날짜 링크를 클릭한 시작 날짜로 클릭 날짜가 시작 날짜와 종료 날짜 사이 포함되어야 합니다.
예: 2024-05-01
string
endYmd 종료 날짜 링크를 클릭한 종료 날짜로 클릭 날짜가 시작 날짜와 종료 날짜 사이 포함되어야 합니다.
시작 날짜와 종료 날짜 범위는 최대 1달입니다.
예: 2024-05-31
string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnClickList" type="button">Get click list</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnClickList").on('click', function(evt){
		evt.preventDefault();

		const linkId = 'y6Tg';
		const domain = 'https://vvd.bz';
		const startYmd = '2024-05-01';
		const endYmd = '2024-05-31';

		$.ajax({
			type: 'GET',
			url: 'https://vivoldi.com/api/statistics/v1/clicks-by-date?linkId='+linkId+'&domain='+domain+'&startYmd='+startYmd+'&endYmd='+endYmd,
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				console.log(res);
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$linkId = "y6Tg";
$domain = "https://vvd.bz";
$startYmd = "2024-05-01";
$endYmd = "2024-05-31";
$url = "https://vivoldi.com/api/statistics/v1/clicks-by-date?linkId=$linkId&domain=$domain&startYmd=$startYmd&endYmd=$endYmd";

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ClickList {
	public static void main(String[] args) {
		try (HttpClient client = HttpClient.newBuilder().build()) {
            String nm = URLEncoder.encode("my test group", StandardCharsets.UTF_8);
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/statistics/v1/clicks-by-date?linkId=y6Tg&domain=https://vvd.bz&startYmd=2024-05-01&endYmd=2024-05-31"))
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .GET()
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println(json.getString("result"));
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result":[
        {
            "ymd":"2024-05-01",
            "linkId":"y6Tg",
            "domain":"https://vvd.bz",
            "acesCnt":384,
            "pernCnt":295,
        },
        {
            "ymd":"2024-05-02",
            "linkId":"y6Tg",
            "domain":"https://vvd.bz",
            "acesCnt":18543,
            "pernCnt":15691,
        }
        {
            "ymd":"2024-05-03",
            "linkId":"y6Tg",
            "domain":"https://vvd.bz",
            "acesCnt":5408,
            "pernCnt":5006,
        }
    ]
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string
result 통계 목록:
필드 필드 설명 설명 유형
ymd 날짜 - string
linkId 링크 ID - string
domain 도메인 - string
acesCnt 클릭 수 링크 클릭 수 int
pernCnt 클릭 사람 수 링크를 클릭한 사람 수 int
array

그룹 목록

생성된 링크 그룹의 목록을 조회합니다.

Request:
Get /api/group/v1/list HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: -
Request:
필드 필드 설명 설명 필수 유형
grpIdx 그룹 ID 그룹 ID로 목록을 조회합니다. int
nm 그룹 이름 그룹 이름을 설정하면 그룹 목록을 조회할 때 그룹 이름을 검색하여 조회합니다.
그룹 이름 검색은 equals 조회가 아닌 like 조회입니다.
string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnGroupList" type="button">Get group list</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnGroupList").on('click', function(evt){
		evt.preventDefault();

		const nm = encodeURI('my test group');

		$.ajax({
			type: 'GET',
			url: 'https://vivoldi.com/api/group/v1/list?nm='+nm,
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				console.log(res);
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$nm = urlencode("my test group");
$url = "https://vivoldi.com/api/group/v1/list?nm=$nm";

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class GroupList {
	public static void main(String[] args) {
		try (HttpClient client = HttpClient.newBuilder().build()) {
            String nm = URLEncoder.encode("my test group", StandardCharsets.UTF_8);
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/group/v1/list?nm="+nm))
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .GET()
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println(json.getString("result"));
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result":[
        {
            "idx":1,
            "nm":"쿠팡 전자제품",
            "memo":"10만원 ~ 50만원 제품",
            "linkCnt":112,
            "blockOverseasSticsYn":"N",
            "notfSubscYn":"N",
            "kakaoNotifyYn":"N",
            "pushNotifyYn":"N",
            "mailNotifyYn":"N",
            "clksIpFilteringYn":"N",
            "regYmdt":"2019-10-20 02:30:00",
            "modYmdt":"2019-10-20 02:30:00"
        },
        {
            "idx":2,
            "nm":"쿠팡 전자제품 (100만원 이상)",
            "memo":"100만원 이상 제품",
            "linkCnt":68,
            "blockOverseasSticsYn":"N",
            "notfSubscYn":"Y",
            "kakaoNotifyYn":"N",
            "pushNotifyYn":"Y",
            "mailNotifyYn":"N",
            "clksIpFilteringYn":"Y",
            "regYmdt":"2019-10-21 15:30:20",
            "modYmdt":"2019-10-22 11:20:50"
        }
    ]
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string
result 그룹 목록:
필드 필드 설명 설명 유형
idx 그룹ID - int
nm 이름 - string
memo 메모 - string
linkCnt 링크 수 그룹에 연결된 링크 수 int
blockOverseasSticsYn 해외통계 차단 Y:사용함, N:사용 안함 Y or N
notfSubscYn 푸시구독 Y:사용함, N:사용 안함 Y or N
kakaoNotifyYn 클릭 수 카톡 알림 Y:사용함, N:사용 안함 Y or N
pushNotifyYn 클릭 수 푸시 알림 Y:사용함, N:사용 안함 Y or N
mailNotifyYn 클릭 수 메일 알림 Y:사용함, N:사용 안함 Y or N
clksIpFilteringYn 클릭 수 IP 필터링 Y:사용함, N:사용 안함 Y or N
regYmdt 생성 날짜 그룹이 생성된 날짜 Date
modYmdt 수정 날짜 그룹이 수정된 날짜 Date
array

유효기간, 비밀번호, 최대 클릭 허용 수가 설정된 링크 검증

본 API는 프리미엄 요금제부터 사용할 수 있습니다.

링크 접속에 제한을 할 때 유효기간, 비밀번호, 최대 클릭 허용 수를 설정합니다.
사용자들이 비볼디에서 생성한 링크를 클릭하면 상관없지만 만약, 브라우저에서 긴 URL로 직접 접속을 할 경우 검증할 방법이 없습니다.
비볼디는 이러한 문제를 해결하기 위해 별도의 JavaScript SDK를 제공합니다.

긴 링크의 페이지에 비볼디에서 제공하는 SDK를 추가하면 SDK에서 해당 링크의 정보를 조회한 후 유효기간, 비밀번호, 최대 클릭 허용 수를 체크하고
다시 비볼디의 짧은 링크로 Redirect 처리하거나 접근을 차단합니다.

귀하의 이벤트 또는 프로모션 페이지에 비볼디에서 제공하는 스크립트를 <head>...</head> 사이에 추가하고 단 1줄의 코드 작성만으로 쉽게 검증할 수 있습니다.

귀하의 페이지에 아래와 같이 비볼디의 스크립트를 추가하세요:

<html>
<head>
<title>샘플 페이지</title>
<script src="https://opencdn.vivoldi.com/js/v1/link.validate.min.js?v=202401191" type="text/javascript"></script>
<script>
const linkId = 'xY5h';   // 생성한 링크ID
const domain = 'https://vvd.bz';   // 링크 도메인 (vvd.bz 또는 vvd.im)
const apiKey = 'oc3w9m4ytso9mv5e8yse9XXXXXXXXXX';   // 귀하의 API Key
vvdLinkValidate(linkId, domain, apiKey);   // 비볼디에서 제공하는 SDK의 함수 호출
</script>
</head>

<body>
.
.
.
</body>
</html>
Request:
Get /api/validate/v1/link HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
Request 항목 설명:
필드 필드 설명 설명 필수 유형
linkId 링크 ID 유효기간, 비밀번호, 최대 클릭 허용 수가 설정된 링크의 ID string
domain 도메인 생성된 링크의 도메인 string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnValidate" type="button">Get validate</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnValidate").on('click', function(evt){
		evt.preventDefault();

		$.ajax({
			type: 'GET',
			url: 'https://vivoldi.com/api/validate/v1/link?linkId=4Rug&domain=https://vvd.bz',
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				console.log(res.result);
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$linkId = "4Rug";
$domain = "https://vvd.bz";
$url = "https://vivoldi.com/api/validate/v1/link?linkId=$linkId&domain=$domain";

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class LinkValidate {
	public static void main(String[] args) {
		try (HttpClient client = HttpClient.newBuilder().build()) {
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/validate/v1/link?linkId=4Rug&domain=https://vvd.bz"))
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .GET()
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println(json.getString("result"));
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result": {
        "linkId": "xY5h",
        "domain": "https://vvd.bz",
        "expireUseYn": "N",
        "expireYn": "N",
        "expireUrl": "https://",
        "acesMaxUseYn": "Y",
        "acesMaxYn": "Y",
        "acesMaxCnt": 1000,
        "acesCnt": 1,
        "pernCnt": 1,
        "agentKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "url": "https://vvd.bz/xY5h",
        "pwdUseYn": "Y",
        "pwdConfirmYn: "Y"
    }
}
Response 항목 설명:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string
result
필드 필드 설명 설명 유형
linkId 링크ID - string
domain 도메인 - string
expireUseYn 유효기간 설정여부 Y:유효기간 설정됨, N:유효기간이 설정되지 않음.
링크 그룹에 유효기간이 설정되어 있을 경우 링크의 유효기간은 무시됩니다.
Y or N
expireYn 유효기간 만료여부 Y:유효기간 만료됨, N:유효기간이 만료되지 않음 Y or N
expireUrl 유효기간 만료URL 유효기간이 만료될 경우 이동될 URL
링크 그룹에 유효기간 만료URL이 설정된 경우 링크의 만료URL은 무시됩니다.
string
acesMaxUseYn 최대 클릭 허용 수 설정 여부 Y:최대 클릭 허용 수가 설정됨, N:최대 클릭 허용 수가 설정되지 않음.
링크 그룹에 최대 클릭 허용 수가 설정된 경우 링크의 허용 수 설정는 무시됩니다.
Y or N
acesMaxYn 최대 클릭 허용 수 초과여부 Y:최대 클릭 허용 수 초과됨, N:최대 클릭 허용 수 초과안됨 Y or N
acesMaxCnt 최대 클릭 허용 수 설정된 최대 클릭 허용 수 int
acesCnt 링크 클릭 수 현재까지 클릭된 수 int
pernCnt 링크 사람 수 클릭한 사람 수 int
agentKey 사용자 키 값이 존재할 경우 비볼디의 짧은 링크를 클릭한 상태입니다.
값이 없을 경우 브라우저에서 긴 URL로 바로 접속한 경우입니다.
값이 존재할 경우 3시간 후 자동으로 값이 초기화됩니다.
string
url 단축URL 비볼디의 짧은 링크 string
pwdUseYn 비밀번호 설정여부 Y: 비밀번호가 설정됨, N:비밀번호가 설정되지 않음
링크 그룹에 비밀번호가 설정된 경우 링크의 비밀번호는 무시됩니다.
Y or N
pwdConfirmYn 비밀번호 인증 완료여부 Y: 사용자가 단축URL에 접속한 후 비밀번호를 입력하고 인증에 성공함.
N:브라우저에서 긴 URL로 접속하였거나 비밀번호 인증이 완료되지 않은 상태.
비밀번호 인증이 완료된 후 3시간이 경과하면 값이 N으로 처리되므로 다시 인증을 해야 합니다.
Y or N
object

쿠폰 생성

본 API는 퍼스널 요금제부터 사용할 수 있습니다.

할인 쿠폰을 생성합니다. 만약, 한번에 여러 개의 쿠폰을 만들고자 한다면 대시보드에서 쿠폰을 만드세요.
API를 이용하면 쿠폰 이미지를 업로드할 수 없습니다.
이 경우, 대시보드에서 쿠폰 그룹을 만들 때 쿠폰 이미지를 업로드하고 쿠폰 생성 시 그룹을 지정할 수 있습니다.
쿠폰을 생성할 때 쿠폰 그룹을 지정하면 일부 설정은 무시되고 쿠폰 그룹의 설정이 적용됩니다.

Request:
Post /api/coupon/v1/create HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/json
Request:
필드 필드 설명 설명 필수 유형
cpnNo 쿠폰 번호 대문자의 영문자와 숫자로 조합된 8~16자리의 쿠폰 번호입니다. 특수 문자는 쿠폰 번호에 사용할 수 없습니다.
값이 비어있으면 쿠폰 번호가 시스템에 의해 자동으로 생성됩니다.
string
grpIdx 쿠폰 그룹 쿠폰 그룹은 쿠폰의 분류를 관리하는데 사용되며, 그룹 설정과 쿠폰 설정이 중복될 경우 쿠폰 설정은 무시됩니다.
그룹IDX는 대시보드의 쿠폰 그룹 페이지에서 확인할 수 있습니다.
기본값: 0
int
tmplIdx 쿠폰 템플릿 쿠폰 템플릿은 쿠폰에 대한 설명과 사용처, 사용 방법, 주의 사항을 사용자에게 알려줄 때 사용됩니다.
템플릿IDX는 대시보드의 쿠폰 템플릿 페이지에서 확인할 수 있습니다.
기본값: 0
int
nm 쿠폰 이름 쿠폰의 이름은 쿠폰 페이지에 노출됩니다. string
discTypeIdx 할인 유형 쿠폰의 할인 유형(요율 또는 금액)을 설정합니다.
457:요율 할인(%), 458:금액 할인
요율 할인: 쿠폰에 대한 백분율 할인을 제공할 때 사용됩니다.
금액 할인: 입력된 금액 만큼 할인을 제공할 때 사용됩니다.
int
disc 할인 값 할인 유형이 요율(457)일 때 1% ~ 100% 사이의 값을 입력합니다.
할인 유형이 금액(458)일 때 할인할 금액을 입력합니다.
double
discCurrency 금액 화폐 할인 유형이 금액(458)일 때 화폐 단위를 설정할 수 있습니다.
KRW:원화, USD:미국 달러, JPY:일본 엔화, EUR:유럽 유로
기본값: KRW
string
strtYmd 유효기간 시작일 쿠폰을 언제부터 사용할 수 있는지 유효기간의 시작일을 설정합니다.
yyyy-mm-dd 날짜 형식으로 10자리 값.
예: 2024-10-01
date
endYmd 유효기간 만료일 쿠폰을 언제까지 사용할 수 있는지 유효기간의 만료일을 설정합니다.
yyyy-mm-dd 날짜 형식으로 10자리 값.
예: 2024-12-31
date
onsiteYn 현장쿠폰 여부 이 값이 Y이면 쿠폰 페이지에서 쿠폰을 사용할 수 있는 버튼이 표시됩니다.
사용자가 매장 직원에게 쿠폰을 보여주면 직원이 쿠폰을 사용하는 방식입니다. 오프라인 매장을 운영하고 있다면 유용한 기능입니다.
기본값: N
Y or N
memo 메모 쿠폰을 관리하는 내부 용도로 사용될 수 있습니다.
메모는 사용자에게 노출되지 않습니다.
string
url URL URL을 입력하면 쿠폰 페이지에 “쿠폰 사용하러 가기” 버튼이 표시되고 클릭하면 입력된 URL로 이동됩니다.
쿠폰 이미지가 업로드된 경우 이미지를 클릭하여도 URL로 이동됩니다.
string
useLimit 1인당 최대 쿠폰 사용 횟수 쿠폰을 최대 몇 번까지 사용할 수 있는지 횟수를 설정합니다.
1인당 쿠폰 사용 횟수 “2회 ~ 5회”까지는 비볼디에서 제공하는 REST API를 이용하여 쿠폰사용 처리를 할 때 필요합니다.
이때 사용자ID 값은 반드시 입력되어야 합니다.
쿠폰 사용을 대시보드에서 수동으로 관리할 때는 “무제한”, “1회” 중 1가지만 선택할 수 있습니다.
“무제한”을 선택하면 누구나 횟수 제한없이 쿠폰을 사용할 수 있습니다.
0:무제한, 1:1회 제한, 2:2회 제한, 3:3회 제한, 4:4회 제한, 5:5회 제한
int
color 글자 색상 쿠폰 페이지에서 쿠폰 글자의 색상을 설정합니다.
HEX 값으로 입력되어야 하며, 투명도를 포함한 최대 9자리까지 입력할 수 있습니다.
기본 값: #4F4F4FFF
string
background 배경 색상 쿠폰 페이지에서 쿠폰의 배경 색상을 설정합니다.
HEX 값으로 입력되어야 하며, 투명도를 포함한 최대 9자리까지 입력할 수 있습니다.
기본 값: #FFFFFFFF
string
userId 사용자 ID 누구에게 쿠폰을 발급하였는지 그리고 누가 쿠폰을 사용하였는지 관리하는데 사용됩니다.
1인당 최대 쿠폰 사용 횟수의 값이 2 ~ 5인 경우 사용자 ID는 반드시 입력되어야 합니다.
일반적으로 웹사이트에 가입한 회원의 로그인ID를 입력합니다.
string
userNm 사용자 이름 누구에게 쿠폰을 발급할 것인지 이미 알고 있다면 쿠폰을 사용할 사용자의 이름을 입력합니다.
쿠폰 발급과 사용 처리에 대한 관리를 할 때 필요합니다.
string
userPhnno 사용자 연락처 쿠폰을 사용할 사용자의 연락처를 설정합니다. string
userEml 사용자 이메일 쿠폰을 사용할 사용자의 이메일을 설정합니다. string
userEtc1 사용자 기타 정보1 내부 관리 용도로 사용자의 추가 정보를 설정합니다. string
userEtc2 사용자 기타 정보2 내부 관리 용도로 사용자의 추가 정보를 설정합니다. string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnCreateCoupon" type="button">Create Coupon</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnCreateCoupon").on('click', function(evt){
		evt.preventDefault();
		const data = JSON.stringify({
			'cpnNo':'',  // auto create
			'grpIdx':271,
			'tmplIdx':0,
			'nm':'5,000원 할인 쿠폰',
			'discTypeIdx':458,
			'disc':5000,
			'strtYmd':'2024-10-01',
			'endYmd':'2025-12-31',
			'memo':'신규 회원가입, Address:211.111.222.33',
			'url':'https://bestshop.com/product/bags/42316',
			'useLimit':1,
			'userId':'att78z',
			'userNm':'홍길동',
			'userPhnno':'010-1111-2345',
			'userEml':'test@gmail.com',
			'userEtc1':'VIP 회원'
		});
		$.ajax({
			type: 'POST',
			url: 'https://vivoldi.com/api/coupon/v1/create',
			data: data,
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			contentType: 'application/json; charset=utf-8',
			dataType: 'json',
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				alert('Coupon number: ' + res.result);
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$url = "https://vivoldi.com/api/coupon/v1/create";
$params = array (
	"cpnNo" => "",  // auto create
	"grpIdx" => 271,
	"tmplIdx" => 0,
	"nm" => "5,000원 할인 쿠폰",
	"discTypeIdx" => 458,
	"disc" => 5000,
	"strtYmd" => "2024-10-01",
	"endYmd" => "2025-12-31",
	"memo" => "신규 회원가입, Address:211.111.222.33",
	"url" => "https://bestshop.com/product/bags/42316",
	"useLimit" => 1,
	"userId" => "att78z",
	"userNm" => "홍길동",
	"userPhnno" => "010-1111-2345",
	"userEml" => "test@gmail.com",
	"userEtc1" => "VIP 회원"
);
$body = json_encode($params);

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX",
	"Content-Type: application/json"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class CreateCoupon {
    public static void main(String[] args) {
        try (HttpClient client = HttpClient.newBuilder().build()) {
            JSONObject params = new JSONObject();
            params.put("cpnNo", "");  // auto create
			params.put("grpIdx", 271);
			params.put("tmplIdx", 0);
			params.put("nm", "5,000원 할인 쿠폰");
			params.put("discTypeIdx", 458);
			params.put("disc", 5000);
			params.put("strtYmd", "2024-10-01");
			params.put("endYmd", "2025-12-31");
			params.put("memo", "신규 회원가입, Address:211.111.222.33");
			params.put("url", "https://bestshop.com/product/bags/42316");
			params.put("useLimit", 1);
			params.put("userId", "att78z");
			params.put("userNm", "홍길동");
			params.put("userPhnno", "010-1111-2345");
			params.put("userEml", "test@gmail.com");
			params.put("userEtc1", "VIP 회원");

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/coupon/v1/create"))
                .header("Content-Type", "application/json")
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .POST(HttpRequest.BodyPublishers.ofString(params.toString()))
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println("Coupon number: " + json.getString("result"));
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
    }
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result":"ZJLF0399WQBEQZJM"
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string
result 응답 값 (쿠폰 번호) string

쿠폰 수정

본 API는 퍼스널 요금제부터 사용할 수 있습니다.

생성된 쿠폰의 정보를 변경합니다.
쿠폰에 그룹을 지정하면 일부 설정은 무시되고 쿠폰 그룹의 설정이 적용됩니다.
이미 사용된 쿠폰은 “메모”만 수정할 수 있고 이외 정보는 변경할 수 없습니다.

Request:
Put /api/coupon/v1/edit HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/json
Request:
필드 필드 설명 설명 필수 유형
cpnNo 쿠폰 번호 정보를 변경할 쿠폰 번호입니다. “-” 기호를 제외한 쿠폰 번호만 입력하세요. string
grpIdx 쿠폰 그룹 쿠폰 그룹은 쿠폰의 분류를 관리하는데 사용되며, 그룹 설정과 쿠폰 설정이 중복될 경우 쿠폰 설정은 무시됩니다.
그룹IDX는 대시보드의 쿠폰 그룹 페이지에서 확인할 수 있습니다.
기본값: 0
int
tmplIdx 쿠폰 템플릿 쿠폰 템플릿은 쿠폰에 대한 설명과 사용처, 사용 방법, 주의 사항을 사용자에게 알려줄 때 사용됩니다.
템플릿IDX는 대시보드의 쿠폰 템플릿 페이지에서 확인할 수 있습니다.
기본값: 0
int
nm 쿠폰 이름 쿠폰의 이름은 쿠폰 페이지에 노출됩니다. string
discTypeIdx 할인 유형 쿠폰의 할인 유형(요율 또는 금액)을 설정합니다.
457:요율 할인(%), 458:금액 할인
요율 할인: 쿠폰에 대한 백분율 할인을 제공할 때 사용됩니다.
금액 할인: 입력된 금액 만큼 할인을 제공할 때 사용됩니다.
int
disc 할인 값 할인 유형이 요율(457)일 때 1% ~ 100% 사이의 값을 입력합니다.
할인 유형이 금액(458)일 때 할인할 금액을 입력합니다.
double
discCurrency 금액 화폐 할인 유형이 금액(458)일 때 화폐 단위를 설정할 수 있습니다.
KRW:원화, USD:미국 달러, JPY:일본 엔화, EUR:유럽 유로
기본값: KRW
string
strtYmd 유효기간 시작일 쿠폰을 언제부터 사용할 수 있는지 유효기간의 시작일을 설정합니다.
yyyy-mm-dd 날짜 형식으로 10자리 값.
예: 2024-10-01
date
endYmd 유효기간 만료일 쿠폰을 언제까지 사용할 수 있는지 유효기간의 만료일을 설정합니다.
yyyy-mm-dd 날짜 형식으로 10자리 값.
예: 2024-12-31
date
onsiteYn 현장쿠폰 여부 이 값이 Y이면 쿠폰 페이지에서 쿠폰을 사용할 수 있는 버튼이 표시됩니다.
사용자가 매장 직원에게 쿠폰을 보여주면 직원이 쿠폰을 사용하는 방식입니다. 오프라인 매장을 운영하고 있다면 유용한 기능입니다.
Y or N
memo 메모 쿠폰을 관리하는 내부 용도로 사용될 수 있습니다.
메모는 사용자에게 노출되지 않습니다.
string
url URL URL을 입력하면 쿠폰 페이지에 “쿠폰 사용하러 가기” 버튼이 표시되고 클릭하면 입력된 URL로 이동됩니다.
쿠폰 이미지가 업로드된 경우 이미지를 클릭하여도 URL로 이동됩니다.
string
useLimit 1인당 최대 쿠폰 사용 횟수 쿠폰을 최대 몇 번까지 사용할 수 있는지 횟수를 설정합니다.
1인당 쿠폰 사용 횟수 “2회 ~ 5회”까지는 비볼디에서 제공하는 REST API를 이용하여 쿠폰사용 처리를 할 때 필요합니다.
이때 사용자ID 값은 반드시 입력되어야 합니다.
쿠폰 사용을 대시보드에서 수동으로 관리할 때는 “무제한”, “1회” 중 1가지만 선택할 수 있습니다.
“무제한”을 선택하면 누구나 횟수 제한없이 쿠폰을 사용할 수 있습니다.
0:무제한, 1:1회 제한, 2:2회 제한, 3:3회 제한, 4:4회 제한, 5:5회 제한
int
color 글자 색상 쿠폰 페이지에서 쿠폰 글자의 색상을 설정합니다.
HEX 값으로 입력되어야 하며, 투명도를 포함한 최대 9자리까지 입력할 수 있습니다.
기본 값: #4F4F4FFF
string
background 배경 색상 쿠폰 페이지에서 쿠폰의 배경 색상을 설정합니다.
HEX 값으로 입력되어야 하며, 투명도를 포함한 최대 9자리까지 입력할 수 있습니다.
기본 값: #FFFFFFFF
string
userId 사용자 ID 누구에게 쿠폰을 발급하였는지 그리고 누가 쿠폰을 사용하였는지 관리하는데 사용됩니다.
1인당 최대 쿠폰 사용 횟수의 값이 2 ~ 5인 경우 사용자 ID는 반드시 입력되어야 합니다.
일반적으로 웹사이트에 가입한 회원의 로그인ID를 입력합니다.
string
userNm 사용자 이름 누구에게 쿠폰을 발급할 것인지 이미 알고 있다면 쿠폰을 사용할 사용자의 이름을 입력합니다.
쿠폰 발급과 사용 처리에 대한 관리를 할 때 필요합니다.
string
userPhnno 사용자 연락처 쿠폰을 사용할 사용자의 연락처를 설정합니다. string
userEml 사용자 이메일 쿠폰을 사용할 사용자의 이메일을 설정합니다. string
userEtc1 사용자 기타 정보1 내부 관리 용도로 사용자의 추가 정보를 설정합니다. string
userEtc2 사용자 기타 정보2 내부 관리 용도로 사용자의 추가 정보를 설정합니다. string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnEditCoupon" type="button">Edit Coupon</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnEditCoupon").on('click', function(evt){
		evt.preventDefault();
		const data = JSON.stringify({
			'cpnNo':'ZJLF0399WQBEQZJM',
			'nm':'40% 할인 쿠폰',
			'discTypeIdx':457,
			'disc':40
		});
		$.ajax({
			type: 'PUT',
			url: 'https://vivoldi.com/api/coupon/v1/edit',
			data: data,
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			contentType: 'application/json; charset=utf-8',
			dataType: 'json',
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				alert('success!');
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$url = "https://vivoldi.com/api/coupon/v1/edit";
$params = array (
	"cpnNo" => "ZJLF0399WQBEQZJM",
	"nm" => "40% 할인 쿠폰",
	"discTypeIdx" => 457,
	"disc" => 40
);
$body = json_encode($params);

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX",
	"Content-Type: application/json"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class EditCoupon {
    public static void main(String[] args) {
        try (HttpClient client = HttpClient.newBuilder().build()) {
            JSONObject params = new JSONObject();
            params.put("cpnNo", "ZJLF0399WQBEQZJM");
			params.put("nm", "40% 할인 쿠폰");
			params.put("discTypeIdx", 457);
			params.put("disc", 40);

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/coupon/v1/edit"))
                .header("Content-Type", "application/json")
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .PUT(HttpRequest.BodyPublishers.ofString(params.toString()))
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println("Success!");
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
    }
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result":null
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string

쿠폰 삭제

본 API는 퍼스널 요금제부터 사용할 수 있습니다.

생성된 쿠폰을 삭제합니다.
한번에 여러 개의 쿠폰을 삭제하려면 대시보드를 이용하세요.

Request:
Delete /api/coupon/v1/remove HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: -
Request:
필드 필드 설명 설명 필수 유형
cpnNo 쿠폰 번호 삭제할 쿠폰번호. string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnDeleteCoupon" type="button">Delete Coupon</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnDeleteCoupon").on('click', function(evt){
		evt.preventDefault();

		$.ajax({
			type: 'DELETE',
			url: 'https://vivoldi.com/api/coupon/v1/remove?cpnNo=ZJLF0399WQBEQZJM',
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				alert('Success!');
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$cpnNo = "ZJLF0399WQBEQZJM";
$url = "https://vivoldi.com/api/coupon/v1/remove?cpnNo=$cpnNo";

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class DeleteCoupon {
	public static void main(String[] args) {
		try (HttpClient client = HttpClient.newBuilder().build()) {
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/link/v1/remove?cpnNo=ZJLF0399WQBEQZJM"))
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .DELETE()
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println("Success!");
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":""
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string

쿠폰 검증

본 API는 퍼스널 요금제부터 사용할 수 있습니다.

“쿠폰 사용” 처리 전 유효한 쿠폰인지 조회하여 검증하는데 사용됩니다.
아래와 같이 쿠폰 검증을 검증합니다.
  • 쿠폰 유효기간 검증. (시작일과 만료일)
  • 1인당 쿠폰 최대 사용가능 횟수 검증.
  • 쿠폰 사용여부 검증.
Request:
Get /api/coupon/v1/validate HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/json
Request 항목 설명:
필드 필드 설명 설명 필수 유형
cpnNo 쿠폰 번호 검증할 쿠폰 번호.
검증에 실패할 경우, Response의 message를 확인하세요.
string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnValidate" type="button">Get validate</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnValidate").on('click', function(evt){
		evt.preventDefault();

		$.ajax({
			type: 'GET',
			url: 'https://vivoldi.com/api/coupon/v1/validate?cpnNo=ZJLF0399WQBEQZJM',
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				console.log('사용 가능한 쿠폰입니다.');
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$cpnNo = "ZJLF0399WQBEQZJM";
$url = "https://vivoldi.com/api/coupon/v1/validate?cpnNo=$cpnNo";

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     echo "사용 가능한 쿠폰입니다.";
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ValidateCoupon {
	public static void main(String[] args) {
		try (HttpClient client = HttpClient.newBuilder().build()) {
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/coupon/v1/validate?cpnNo=ZJLF0399WQBEQZJM"))
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .GET()
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println("사용 가능한 쿠폰입니다.");
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result": null
}
Response 항목 설명:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string

쿠폰 사용

본 API는 퍼스널 요금제부터 사용할 수 있습니다.

대시보드의 쿠폰 목록에서 “쿠폰 사용” 처리를 수동으로 관리할 수 있지만 본 API를 이용하면 귀하의 웹사이트에서 사용자가 쿠폰을 사용할 때 호출하여 자동화할 수 있습니다.

Request:
Put /api/coupon/v1/use HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/json
Request:
필드 필드 설명 설명 필수 유형
cpnNo 쿠폰 번호 “사용 완료” 처리할 쿠폰 번호.
“-” 기호를 제외한 쿠폰 번호만 입력하세요.
string
userId 사용자 ID 누구에게 쿠폰을 발급하였는지 그리고 누가 쿠폰을 사용하였는지 관리하는데 사용됩니다.
1인당 최대 쿠폰 사용 횟수의 값이 2 ~ 5인 경우 사용자 ID는 반드시 입력되어야 합니다.
일반적으로 웹사이트에 가입한 회원의 로그인ID를 입력합니다.
string
memo 메모 쿠폰 사용의 관리 차원에서 메모를 입력할 수 있습니다.
사용자의 IP Address, 쿠폰을 사용한 페이지 및 서비스, 기타 정보를 입력합니다.
1인당 최대 쿠폰 사용 횟수가 무제한일 때 누가 쿠폰을 사용하였는지 알 수 없기 때문에 사용자ID 또는 메모로 관리할 수 있습니다.
string
Examples:
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"/>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
</head>

<body>

<form id="exampleForm">
	<button id="btnUseCoupon" type="button">Use Coupon</button>
</form>

<script type="text/javascript">
$(function(){
	$("#btnUseCoupon").on('click', function(evt){
		evt.preventDefault();
		const data = JSON.stringify({
			'cpnNo':'ZJLF0399WQBEQZJM',
			'userId':'x77hu',
			'memo':'IP Address: 210.123.111.222, Request Page: example.com/shop/bags/p112233'
		});
		$.ajax({
			type: 'PUT',
			url: 'https://vivoldi.com/api/coupon/v1/use',
			data: data,
			headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
			contentType: 'application/json; charset=utf-8',
			dataType: 'json',
			timeout: 5000
		}).done(function(res){
			if (res.code === 0) {
				alert('success!');
			} else {
				alert('code: ' + res.code + ', message: ' + res.message);
			}
		}).fail(function(xhr, textStatus, e){
			alert('error: ' + e);
		});
	});
});
</script>

</body>
</html>
<?php
$url = "https://vivoldi.com/api/coupon/v1/use";
$params = array (
	"cpnNo" => "ZJLF0399WQBEQZJM",
	"userId" => "x77hu",
	"memo" => "IP Address: 210.123.111.222, Request Page: example.com/shop/bags/p112233"
);
$body = json_encode($params);

$headers = array(
	"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX",
	"Content-Type: application/json"
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

$result = curl_exec($ch);

if ($result === FALSE) {
     echo "Error sending: " . curl_error($ch);
} else {
     print_r($result);
}
curl_close($ch);
?>
package com.example;

import org.json.JSONObject;
import org.springframework.http.HttpStatus;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class UseCoupon {
    public static void main(String[] args) {
        try (HttpClient client = HttpClient.newBuilder().build()) {
            JSONObject params = new JSONObject();
            params.put("cpnNo", "ZJLF0399WQBEQZJM");
			params.put("userId", "x77hu");
			params.put("memo", "IP Address: 210.123.111.222, Request Page: example.com/shop/bags/p112233");

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://vivoldi.com/api/coupon/v1/use"))
                .header("Content-Type", "application/json")
                .header("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
                .PUT(HttpRequest.BodyPublishers.ofString(params.toString()))
                .build();

            HttpResponse<String> response;
            try {
                response = client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            if (response != null) {
                if (response.statusCode() == HttpStatus.OK.value()) {
                    String jsonString = response.body();
                    if (jsonString != null && !jsonString.isEmpty()) {
                        JSONObject json = new JSONObject(jsonString);
                        if (json.getInt("code") == 0) {
                            System.out.println("Success!");
                        } else {
                            System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
                        }
                    }
                }
            }
        }
    }
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result":null
}
Response:
필드 설명 유형
code 응답 코드 (0:성공) int
message 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. string

푸시 메시지 보내기

본 API는 비볼디의 단축URL 서비스와 무관하며, 웹사이트를 운영하는 모든 사용자를 대상으로 합니다.

귀하의 웹사이트에 방문한 사용자에게 푸시 메시지를 전송하기 위해서는 사용자가 웹브라우저의 “알림 권한”에 동의해야 합니다.
알림 권한에 거부할 경우, 푸시 메시지를 전송할 수 없습니다.

비볼디에서 제공하는 JavaScript SDK를 귀하의 웹사이트에 설치하면 사용자가 웹사이트에 방문했을 때 웹브라우저에서 “알림 권한”에 대한 팝업 창을 표시합니다.
사용자가 권한에 동의하면 대시보드의 “푸시 메시지 -> 웹사이트 푸시 발송” 페이지에 알림 데이타가 목록에 표시됩니다.
만약, 100명의 사용자가 귀하의 웹사이트에서 알림 권한에 동의하였다면 100개의 데이타가 목록에 표시됩니다.
푸시 메시지를 전송하면 목록에 표시되는 모든 사용자에게 메시지가 전송됩니다.

비볼디에서 제공하는 JavaScript SDK 설치는 누구나 할 수 있어 사용자 데이타를 모을 수 있습니다.
하지만 푸시 메시지를 전송하기 위해서는 금액이 충전되어 있어야 합니다.
푸시 메시지 전송에 대한 비용은 전송 건당 10원이며 월 정액제를 신청하시면 횟수 제한없이 무제한 발송이 가능합니다.

JavaScript SDK 설치는 <head>...</head> 사이에 추가하기만 하면 됩니다.

<html>
<head>
<title>example page</title>
<script src="https://opencdn.vivoldi.com/js/webpush.min.js?v=202502051" type="text/javascript"></script>
<script>
const apiKey = 'oc3w9m4ytso9mv5e8yse9XXXXXXXXXX';   // your api key
const publicKey = 'XXXXXYTRlpG8mXXXXXiuBZ6BtjyOfgPsDArFYWF2PxZbY4egmDNias1gEfN_5wftScr39K8BbcjXXXXX';   // "푸시 메시지 -> 도메인 관리" 페이지에서 등록한 도메인의 Public Key
const params = {apiKey:apiKey, publicKey:publicKey};
webpush.register(params);   // 알림 권한 팝업 창 띄우기 (이미 권한을 허용하였다면 팝업이 표시되지 않습니다)
</script>
</head>

<body>
.
.
.
</body>
</html>

API Key는 대시보드의 “개발자 API” 페이지에서 만들 수 있고 publicKey는 “푸시 메시지 -> 도메인 관리” 페이지에서 도메인을 등록하면 목록에서 확인할 수 있습니다.

모든 준비가 완료되었다면 마지막으로, sw.min.js 파일을 새로 만들고 귀하의 웹사이트 root에 업로드하세요.
예: https://example.com/sw.min.js

위 경로로 접속할 때 스크립트가 웹브라우저에 표시되어야 정상적으로 알림이 작동됩니다.
새로 만든 sw.min.js 파일에 아래 코드를 복사하여 붙여넣으세요.

sw.min.js:
'use strict';const a0_0x5374e1=a0_0xe038;(function(_0x1227c0,_0x51a60b){const _0x31ab77=a0_0xe038,_0x20d84d=_0x1227c0();while(!![]){try{const _0x12de05=parseInt(_0x31ab77(0x189))/0x1+-parseInt(_0x31ab77(0x188))/0x2+-parseInt(_0x31ab77(0x175))/0x3+parseInt(_0x31ab77(0x196))/0x4+parseInt(_0x31ab77(0x191))/0x5*(parseInt(_0x31ab77(0x179))/0x6)+parseInt(_0x31ab77(0x190))/0x7*(-parseInt(_0x31ab77(0x18a))/0x8)+parseInt(_0x31ab77(0x181))/0x9*(parseInt(_0x31ab77(0x173))/0xa);if(_0x12de05===_0x51a60b)break;else _0x20d84d['push'](_0x20d84d['shift']());}catch(_0x40c5f5){_0x20d84d['push'](_0x20d84d['shift']());}}}(a0_0x3c7d,0xc9d27));function a0_0xe038(_0x596680,_0x1be660){const _0x3c7dc3=a0_0x3c7d();return a0_0xe038=function(_0xe03880,_0x22c065){_0xe03880=_0xe03880-0x170;let _0x16ce5f=_0x3c7dc3[_0xe03880];return _0x16ce5f;},a0_0xe038(_0x596680,_0x1be660);}function a0_0x3c7d(){const _0x45d9ad=['waitUntil','notification','20673aXYLrA','navigator','title','focus','icon','toLowerCase','image','168378lbyyZD','193689SqVukM','41896sLUVSk','macintosh','close','registration','userAgent','body','1253fKQvUq','2054765fkWElD','install','includes','openWindow','badge','4620004XrYmFj','notificationclick','ko-KR','url','showNotification','parse','바로가기','window','platform','mac','actions','1490bVkBER','action','1993722LznGRH','navigate','button','activate','12Yewkpl','push','matchAll','data','then','addEventListener'];a0_0x3c7d=function(){return _0x45d9ad;};return a0_0x3c7d();}self['addEventListener'](a0_0x5374e1(0x192),_0x220cef=>{self['skipWaiting']();}),self[a0_0x5374e1(0x17e)](a0_0x5374e1(0x178),_0x4e57ea=>{const _0x4e29f9=a0_0x5374e1;_0x4e57ea[_0x4e29f9(0x17f)](clients['claim']());}),self[a0_0x5374e1(0x17e)](a0_0x5374e1(0x17a),function(_0x5b8772){const _0x578b75=a0_0x5374e1,_0x6a0810=JSON[_0x578b75(0x19b)](_0x5b8772[_0x578b75(0x17c)]['text']()),_0x41c647=navigator['language'],_0x3709b8=_0x41c647==='ko'||_0x41c647===_0x578b75(0x198),_0x398015=self[_0x578b75(0x182)]['platform']['toLowerCase']()[_0x578b75(0x193)](_0x578b75(0x171)),_0x570dee=self[_0x578b75(0x182)]['userAgent']['toLowerCase']()[_0x578b75(0x193)](_0x578b75(0x18b)),_0x417e2c={'tag':'renotify','renotify':!![],'body':_0x6a0810[_0x578b75(0x18f)],'icon':_0x6a0810[_0x578b75(0x185)],'badge':_0x6a0810[_0x578b75(0x195)],'requireInteraction':!![],'vibrate':[0x12c,0x64,0x190,0xc8,0x1f4],'data':_0x6a0810,'actions':[{'action':'go','type':_0x578b75(0x177),'title':_0x3709b8?_0x578b75(0x19c):'GO'},{'action':_0x578b75(0x18c),'type':'button','title':_0x3709b8?'닫기':'CLOSE'}]};_0x6a0810[_0x578b75(0x187)]&&(_0x417e2c[_0x578b75(0x187)]=_0x6a0810[_0x578b75(0x187)]),(_0x398015||_0x570dee)&&delete _0x417e2c[_0x578b75(0x172)],_0x5b8772['waitUntil'](self[_0x578b75(0x18d)][_0x578b75(0x19a)](_0x6a0810[_0x578b75(0x183)],_0x417e2c));}),self[a0_0x5374e1(0x17e)](a0_0x5374e1(0x197),function(_0x278188){const _0x1737d2=a0_0x5374e1;_0x278188['notification'][_0x1737d2(0x18c)]();const _0x381024=self['navigator'][_0x1737d2(0x170)][_0x1737d2(0x186)]()[_0x1737d2(0x193)]('mac'),_0x419533=self[_0x1737d2(0x182)][_0x1737d2(0x18e)][_0x1737d2(0x186)]()[_0x1737d2(0x193)](_0x1737d2(0x18b));if(_0x381024||_0x419533)_0x278188[_0x1737d2(0x17f)](clients[_0x1737d2(0x17b)]({'type':_0x1737d2(0x19d)})[_0x1737d2(0x17d)](_0x55a8eb=>{const _0x25611a=_0x1737d2;_0x55a8eb['length']>0x0?(_0x55a8eb[0x0][_0x25611a(0x176)](_0x278188[_0x25611a(0x180)][_0x25611a(0x17c)][_0x25611a(0x199)]),_0x55a8eb[0x0][_0x25611a(0x184)]()):clients[_0x25611a(0x194)](_0x278188[_0x25611a(0x180)]['data'][_0x25611a(0x199)]);}));else switch(_0x278188[_0x1737d2(0x174)]){case'go':_0x278188[_0x1737d2(0x17f)](clients[_0x1737d2(0x194)](_0x278188[_0x1737d2(0x180)][_0x1737d2(0x17c)][_0x1737d2(0x199)]));break;case _0x1737d2(0x18c):break;default:_0x278188['waitUntil'](clients[_0x1737d2(0x194)](_0x278188[_0x1737d2(0x180)][_0x1737d2(0x17c)][_0x1737d2(0x199)]));}});

이제, 귀하의 웹사이트에 접속하면 알림 권한이 표시될 것입니다.
알림 권한을 허용했을 때 비볼디 대시보드의 “웹사이트 푸시 발송” 페이지에 알림 데이타가 조회되는지 확인하세요.