URL Shortener Developer API
Introduction to the developer API
Vivoldi provides a dedicated REST API for your platform or system.
The REST API gives you the freedom to create links from your own servers or mobile apps without having to create links from the Vivoldi dashboard.
The provided REST API can be called from any development language and operating system, including JavaScript, PHP, Java, Android, and iOS.
Before calling the API, an API key must be generated, and the generated API key must be managed so that it is not exposed to others.
You can change your API key once a month, and changing your API key will not affect any links that have already been created.
All APIs are free to use and follow the request specifications set by Vivoldi, and API processing and response speeds vary depending on the plan.
If you get an HTTP 403 error after an API call, specify a separate User-agent value in the header.
Vivoldi blocks some User-agents.
How to call the API
Host: https://vivoldi.com/api HTTP/1.1
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
{
"code": 0,
"message": "",
"result": Object
}
message - The response message, an error message is returned if the response code is non-zero.
result - The response value, returned as a character or JSON object depending on the API type.
Create link
Create 1 shortened link. If you want to create a large number of links, use the "Create Bulk Links" menu in your dashboard.
Post /api/link/v1/create HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
Fields | Field Descriptions | Description | Required | Type |
---|---|---|---|---|
url | Long URLs | The long URL to be redirected to when the generated short link is clicked. | string | |
domain | Domain | Link domain, if the value is empty, the vvd.bz domain is automatically selected. If you are using a random domain from Vivoldi, or if you have integrated your own domain with Vivoldi, you can set that domain. | string | |
grpIdx | Group ID | Setting a group ID will create a link to that group. To check the GroupID, you need to call the "Group List" API to get it. | int | |
brandLinkId | Brand Link ID | If you specify a value, a link will be created with that ID. (If a branded link is set, the domain will be vvd.im, not vvd.bz) If the value is empty, the linkID is generated automatically. | string | |
ttl | Link Title | If the value is empty, it is automatically saved as the webpage title of the long link. | string | |
memo | Notes | You can set additional information that you need for administration without exposing it to users. | string | |
notfSubscYn | Push Link | If the value is Y, when the generated link is clicked, a web push notification pop-up will be displayed before being taken to the long link, and a push message can be sent to all users who have allowed it, if the user has given permission for push notifications. If they disagree or cancel the notification pop-up, they are immediately taken to the original long URL. If no value is entered, the default value is N. To learn more about push subscription links, take a look at the Web Push feature introduction page. | Y or N | |
clksIpFilteringYn | IP filtering for clicks | If the value is Y, then the number of link clicks from the same IP over a 24-hour period will be fixed at 1 instead of continuing to increase. If the link is clicked again after midnight (12am), the click count will be +1. The clicks IP filtering feature can only be set at the time of link creation and the value cannot be changed by subsequent link edits. This feature is available starting with the Personal plan. | Y or N | |
pushNotifyYn | Push notifications | If the value is Y, you can receive clicks push notifications to mobile devices with the Vivoldi app installed whenever a link reaches the number of clicks set in the link settings on the "Settings -> Preferences" page. This feature is available starting with the Personal plan. | Y or N | |
mailNotifyYn | Mail notifications | If the value is Y, you can receive click count information to your Vivoldi subscribed email whenever you reach the number of link clicks set in the link settings on the "Settings -> Preferences" page. This feature is available starting with the Personal plan. | Y or N |
<!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">
url: <input type="text" id="url" name="url" value="https://google.com"/><br/>
domain: <input type="text" id="domain" name="domain" value="https://vvd.bz"/><br/>
<button id="btnCreateLink" type="button">Create Link</button>
</form>
<script type="text/javascript">
$(function(){
$("#btnCreateLink").on('click', function(evt){
evt.preventDefault();
const form = $('#exampleForm')[0];
const data = new FormData(form);
$.ajax({
type: 'POST',
url: 'https://vivoldi.com/api/link/v1/create',
data: data,
headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
processData: false,
contentType: false,
cache: false,
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/v1/create";
$params = array (
"url" => "https://www.facebook.com/vivoldi365",
"domain" => "https://vvd.bz",
);
$headers = array(
"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$result = curl_exec($ch);
if ($result === FALSE) {
echo "Error sending: " . curl_error($ch);
} else {
print_r($result);
}
curl_close($ch);
?>
package com.example;
import okhttp3.*;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
public class CreateLink {
public static void main(String[] args) {
RequestBody requestBody = new FormBody.Builder()
.add("url", "https://www.facebook.com/vivoldi365")
.add("domain", "https://vvd.bz")
.build()
;
Request request = new Request.Builder()
.url("https://vivoldi.com/api/link/v1/create")
.addHeader("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
String jsonText = body.string();
body.close();
JSONObject json = new JSONObject(jsonText);
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")));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
"code":0,
"message":"",
"result":"https://vvd.bz/jH3d"
}
Fields | Description | Type |
---|---|---|
code | Response code (0:Success) | int |
message | The response message, or a related message if the response code is non-zero. | string |
result | Response value (shortened link) | string |
Edit a link
Edit the short link you created.
Post /api/link/v1/edit HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
Fields | Field Descriptions | Description | Required | Type |
---|---|---|---|---|
linkId | Link ID | ID of the generated short link Example: If the address of the short link is "https://vvd.bz/fML", the link ID is fML. | string | |
domain | Domain | The domain of the short link address. Example: If the address of the short link is "https://vvd.bz/fML", the domain is https://vvd.bz. Important: The value https:// or http:// must be entered. If you set it to a domain other than the domain of the generated short link, an error occurs. | string | |
grpIdx | Group ID | Change the group of the generated link. To find out the group ID, you need to call the "Group list" API. | int | |
ttl | Link title | If the value is empty, the link title is not modified. | string | |
memo | Notes | You can set additional information for administration without exposing it to users. If the value is empty, the note will not be modified. | string | |
notfSubscYn | Push Link | If the value is Y, clicking on the generated link will display a web push notification pop-up before being taken to the long link, and if the user has opted in to push notifications, you can send a push message to all users you have allowed. If they disagree or cancel the notification pop-up, they are immediately taken to the original long URL. If you don′t enter a value, then the default value is N. To learn more about push subscription links, click here. | Y or N | |
pushNotifyYn | Push notifications | If the value is Y, you can receive clicks push notifications to mobile devices with the Vivoldi app installed whenever a link reaches the number of clicks set in the link settings on the "Settings -> Preferences" page. This feature is available starting with the Personal plan. | Y or N | |
mailNotifyYn | Mail notifications | If the value is Y, you can receive click count information to your Vivoldi subscribed email whenever you reach the number of link clicks set in the link settings on the "Settings -> Preferences" page. This feature is available starting with the Personal plan. | Y or N |
<!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">
linkId: <input type="text" id="linkId" name="linkId" value="4Rt3"/><br/>
domain: <input type="text" id="domain" name="domain" value="https://vvd.bz"/><br/>
domain: <input type="text" id="ttl" name="ttl" value="새로운 제목"/><br/>
domain: <input type="text" id="memo" name="memo" value="새로운 메모"/><br/>
<button id="btnUpdateLink" type="button">Update Link</button>
</form>
<script type="text/javascript">
$(function(){
$("#btnUpdateLink").on('click', function(evt){
evt.preventDefault();
const form = $('#exampleForm')[0];
const data = new FormData(form);
$.ajax({
type: 'POST',
url: 'https://vivoldi.com/api/link/v1/edit',
data: data,
headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
processData: false,
contentType: false,
cache: false,
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/v1/edit";
$params = array (
"linkId" => "4Rt3",
"domain" => "https://vvd.bz",
"ttl" => "새로운 제목",
"memo" => "새로운 메모"
);
$headers = array(
"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$result = curl_exec($ch);
if ($result === FALSE) {
echo "Error sending: " . curl_error($ch);
} else {
print_r($result);
}
curl_close($ch);
?>
package com.example;
import okhttp3.*;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
public class UpdateLink {
public static void main(String[] args) {
RequestBody requestBody = new FormBody.Builder()
.add("linkId", "4Rt3")
.add("domain", "https://vvd.bz")
.add("ttl", "새로운 제목")
.add("memo", "새로운 메모")
.build()
;
Request request = new Request.Builder()
.url("https://vivoldi.com/api/link/v1/edit")
.addHeader("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
String jsonText = body.string();
body.close();
JSONObject json = new JSONObject(jsonText);
if (json.getInt("code") == 0) {
System.out.println("Success!");
} else {
System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
"code":0,
"message":""
}
Fields | Description | Type |
---|---|---|
code | Response code (0:Success) | int |
message | The response message, or a related message if the response code is non-zero. | string |
Delete a link
Delete the short link you created.
Post /api/link/v1/remove HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
Fields | Field Descriptions | Description | Required | Type |
---|---|---|---|---|
linkId | Link ID | ID of the generated short link Example: If the address of the short link is "https://vvd.bz/fML", the linkID is fML. | string | |
domain | Domain | The domain of the short link address. Example: If the address of the short link is "https://vvd.bz/fML", the domain is https://vvd.bz. Important: The value https:// or http:// must be entered. If you set it to a domain other than the domain of the generated short link, an error occurs. | string |
<!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">
linkId: <input type="text" id="linkId" name="linkId" value="4Rt3"/><br/>
domain: <input type="text" id="domain" name="domain" value="https://vvd.bz"/><br/>
<button id="btnDeleteLink" type="button">Delete Link</button>
</form>
<script type="text/javascript">
$(function(){
$("#btnDeleteLink").on('click', function(evt){
evt.preventDefault();
const form = $('#exampleForm')[0];
const data = new FormData(form);
$.ajax({
type: 'DELETE',
url: 'https://vivoldi.com/api/link/v1/remove',
data: data,
headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
processData: false,
contentType: false,
cache: false,
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/v1/remove";
$params = array (
"linkId" => "4Rt3",
"domain" => "https://vvd.bz"
);
$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, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10000);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$result = curl_exec($ch);
if ($result === FALSE) {
echo "Error sending: " . curl_error($ch);
} else {
print_r($result);
}
curl_close($ch);
?>
package com.example;
import okhttp3.*;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
public class DeleteLink {
public static void main(String[] args) {
RequestBody requestBody = new FormBody.Builder()
.add("linkId", "4Rt3")
.add("domain", "https://vvd.bz")
.build()
;
Request request = new Request.Builder()
.url("https://vivoldi.com/api/link/v1/remove")
.addHeader("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
.delete(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
String jsonText = body.string();
body.close();
JSONObject json = new JSONObject(jsonText);
if (json.getInt("code") == 0) {
System.out.println("Success!");
} else {
System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
"code":0,
"message":""
}
Fields | Description | Type |
---|---|---|
code | Response code (0:Success) | int |
message | The response message, or a related message if the response code is non-zero. | string |
List of links
View a list of created links.
Only URL links can be retrieved; other types of links are not retrieved.
The free plan has a limit of 30 calls to this API per day.
Post /api/link/v1/list HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
Fields | Field Descriptions | Description | Required | Type |
---|---|---|---|---|
linkId | Link ID | Search the list by link ID. | string | |
domain | Domain | Search the list by link domain. The domain must be preceded by the value http:// or https://. | string | |
createTypeIdx | Creation typeIDX | 0:All links, 270:Links created in the Vivoldi dashboard, 272:Links created via API call, 274:Bulk link generation | int | |
grpIdx | Group ID | Retrieve the list by group ID. If there is no value, it is set to the default value of 0. | int | |
url | Long URL | Search the list by long URL. Allows partial search of the URL address. | string | |
ttl | Link Title | Search the list by the title of the link. You can partially search by title. | string | |
brandLinkYn | Branded links | If the link ID is not automatically generated and is set manually, it is a branded link. Y: Enabled (branded link), N: Disabled (automatically generated link) | Y or N | |
notfSubscYn | Push link | Y:Enabled, N:Disabled | Y or N | |
clksIpFilteringYn | Click-through IP filtering | Y:Enabled, N:Disabled | Y or N | |
pushNotifyYn | Clicks Push notifications | Y:Enabled, N:Disabled | Y or N | |
mailNotifyYn | Clicks Mail notifications | Y:Enabled, N:Disabled | Y or N | |
regStartYmdt | Creation start date | The start date when the link was created, which must fall between the start date and end date. Example: 2022-11-08 00:00:00 | Date | |
regEndYmdt | Creation end date | The end date the link was created, which must fall between the start and end dates. Example: 2022-11-08 23:59:59 The end date must be set within one month of the start date. | Date | |
pages | Pages | The pages value is used for pagination and defaults to 1. 한 페이지에 기본적으로 30개의 행이 조회되며 pages의 값이 2일 경우 By default, 30 rows are retrieved on a page, and if the value of PAGES is 2, 30 rows of data are retrieved starting from the 31st row. | int |
<!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">
링크 제목: <input type="text" id="ttl" name="ttl" value=""/><br/>
생성 시작 날짜: <input type="text" id="regStartYmdt" name="regStartYmdt" value="2022-11-01 00:00:00"/><br/>
생성 종료 날짜: <input type="text" id="regEndYmdt" name="regEndYmdt" value="2022-11-30 23:59:59"/><br/>
<button id="btnGroupList" type="button">Get link list</button>
</form>
<script type="text/javascript">
$(function(){
$("#btnLinkList").on('click', function(evt){
evt.preventDefault();
const form = $('#exampleForm')[0];
const data = new FormData(form);
$.ajax({
type: 'GET',
url: 'https://vivoldi.com/api/link/v1/list',
data: data,
headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
processData: false,
contentType: false,
cache: false,
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
$nm = "테스트"; // 검색할 링크 제목
$regStartYmdt = "2022-11-01 00:00:00"; // 링크 생성 시작 날짜
$regㄷEndYmdt = "2022-11-30 23:59:59"; // 링크 생성 종료 날짜
$url = "https://vivoldi.com/api/group/v1/list?nm=$nm®StartYmdt=$regStartYmdt®EndYmdt=$regEndYmdt";
$headers = array(
"Authorization: APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
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 okhttp3.*;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
public class DeleteLink {
public static void main(String[] args) {
String nm = ""; // 검색할 링크 제목
String regStartYmdt = "2022-11-01 00:00:00"; // 링크 생성 시작 날짜
String regEndYmdt = "2022-11-30 23:59:59"; // 링크 생성 종료 날짜
Request request = new Request.Builder()
.url("https://vivoldi.com/api/group/v1/list?nm="+nm+"®StartYmdt="+regStartYmdt+"®EndYmdt="+regEndYmdt)
.addHeader("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
.build();
OkHttpClient client = new OkHttpClient();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
String jsonText = body.string();
body.close();
JSONObject json = new JSONObject(jsonText);
if (json.getInt("code") == 0) {
System.out.println("Success!");
} else {
System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
"code":0,
"message":"",
"result":{
"extra": {
"pages":1,
"nextPages":1,
"nextYn":"N",
"count":2,
"totalCount":2
},
"list": [
{
"linkId":"createpostinglinks",
"domain":"https://vvd.im",
"typeIdx":103,
"typeNm":"URL",
"ttl":"게시물 링크를 이용한 유튜브 동영상을 추가하여 짧은 링크 만들기",
"memo":"",
"url":"https://vvd.im/createpostinglinks",
"grpIdx":0,
"grpNm":"",
"acesCnt":5072,
"acesCntToday":315,
"lastClkYmdt":"2022-11-07 04:45:10",
"longUrl":"https://vivoldi.com/blog/url-shortener/create-posts-link-url-shortener/",
"blockOverseasSticsYn":"N",
"notfSubscYn":"N",
"kakaoNotifyYn":"N",
"pushNotifyYn":"N",
"mailNotifyYn":"N",
"clksIpFilteringYn":"N",
"regYmdt":"2022-11-02 04:27:05",
"modYmdt":"2022-11-02 04:27:05"
},
{
"linkId":"4Rth",
"domain":"https://vvd.bz",
"typeIdx":103,
"typeNm":"URL",
"ttl":"NAVER",
"memo":"",
"url":"https://vvd.bz/4Rth",
"grpIdx":128,
"grpNm":"테스트",
"acesCnt":19,
"acesCntToday":3,
"lastClkYmdt":"2022-11-07 17:20:40",
"longUrl":"https://www.naver.com",
"blockOverseasSticsYn":"N",
"notfSubscYn":"N",
"kakaoNotifyYn":"N",
"pushNotifyYn":"Y",
"mailNotifyYn":"N",
"clksIpFilteringYn":"Y",
"regYmdt":"2022-11-07 17:10:22",
"modYmdt":"2022-11-07 17:10:22"
}
]
}
}
Fields | Description | Type | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
code | 응답 코드 (0:성공) | int | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
message | 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. | string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result | extra (추가 정보)
list (링크 목록) - Array
| array |
Group List
Gets a list of created link groups.
Post /api/group/v1/list HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
필드 | 필드 설명 | 설명 | 필수 | 유형 |
---|---|---|---|---|
grpIdx | 그룹 ID | 그룹 ID로 목록을 조회합니다. | int | |
nm | 그룹 이름 | 그룹 이름을 설정하면 그룹 목록을 조회할 때 그룹 이름을 검색하여 조회합니다. 그룹 이름 검색은 equals 조회가 아닌 like 조회입니다. | string |
<!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">
그룹 이름: <input type="text" id="nm" name="nm" value=""/><br/>
<button id="btnGroupList" type="button">Get group list</button>
</form>
<script type="text/javascript">
$(function(){
$("#btnGroupList").on('click', function(evt){
evt.preventDefault();
const form = $('#exampleForm')[0];
const data = new FormData(form);
$.ajax({
type: 'GET',
url: 'https://vivoldi.com/api/group/v1/list',
data: data,
headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
processData: false,
contentType: false,
cache: false,
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
$nm = ""; // 검색할 그룹 이름
$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, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
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 okhttp3.*;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
public class DeleteLink {
public static void main(String[] args) {
String nm = ""; // 검색할 그룹 이름
Request request = new Request.Builder()
.url("https://vivoldi.com/api/group/v1/list?nm="+nm)
.addHeader("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
.build();
OkHttpClient client = new OkHttpClient();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
String jsonText = body.string();
body.close();
JSONObject json = new JSONObject(jsonText);
if (json.getInt("code") == 0) {
System.out.println("Success!");
} else {
System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
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"
}
]
}
필드 | 설명 | 유형 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
code | 응답 코드 (0:성공) | int | ||||||||||||||||||||||||||||||||||||||||||||||||||||
message | 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. | string | ||||||||||||||||||||||||||||||||||||||||||||||||||||
result | 그룹 목록:
| array |
Validate links with expiration dates, passwords, and maximum clicks allowed
This API is available on the Premium plan.
When you restrict access to a link, you set an expiration date, password, and maximum number of clicks allowed.
If users click on a link generated by Vivoldi, it′s fine, but if they go directly to a long URL in their browser, there′s no way to validate it.
Vivoldi provides a separate JavaScript SDK to solve this problem.
When you add the SDK to a page with a long link, the SDK retrieves the link′s information and checks the expiration date, password, and maximum number of clicks allowed.
Redirect back to the Vivoldi short link or block access.
Add the script provided by Vivoldi to your event or promotion page between the
Add Vivoldi′s script to your page as shown below:
<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>
Post /api/validate/v1/link HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
필드 | 필드 설명 | 설명 | 필수 | 유형 |
---|---|---|---|---|
linkId | 링크 ID | 유효기간, 비밀번호, 최대 클릭 허용 수가 설정된 링크의 ID | string | |
domain | 도메인 | 생성된 링크의 도메인 | string |
<!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">
링크 ID: <input type="text" id="linkId" name="linkId" value="xY5h"/><br/>
링크 도메인: <input type="text" id="domain" name="domain" value="https://vvd.bz"/><br/>
<button id="btnValidate" type="button">Get validate</button>
</form>
<script type="text/javascript">
$(function(){
$("#btnValidate").on('click', function(evt){
evt.preventDefault();
const form = $('#exampleForm')[0];
const data = new FormData(form);
$.ajax({
type: 'GET',
url: 'https://vivoldi.com/api/validate/v1/link',
data: data,
headers: {'Authorization':'APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'},
processData: false,
contentType: false,
cache: false,
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 = "xY5h"; // 링크 ID
$domain = urlencode("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, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
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 okhttp3.*;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
public class LinkValidate {
public static void main(String[] args) {
String linkId = "xY5h"; // 링크 ID
String domain = URLEncoder.encode("https://vvd.bz", StandardCharsets.UTF_8); // 링크 도메인
Request request = new Request.Builder()
.url("https://vivoldi.com/api/validate/v1/link?linkId="+linkId+"&domain="+domain)
.addHeader("Authorization", "APIKey oc3w9m4ytso9mv5e8yse9XXXXXXXXXX")
.build();
OkHttpClient client = new OkHttpClient();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
String jsonText = body.string();
body.close();
JSONObject json = new JSONObject(jsonText);
if (json.getInt("code") == 0) {
System.out.println("Success!");
} else {
System.out.println("Failed: " + String.format("[%d] %s", json.getInt("code"), json.getString("message")));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
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"
}
}
필드 | 설명 | 유형 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
code | 응답 코드 (0:성공) | int | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
message | 응답 메시지, 응답 코드가 0이 아닐 경우 관련 메시지가 리턴됨. | string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result |
| object |
푸시 메시지 전송을 위한 웹 브라우저에서 알림 권한 동의 처리
본 API는 비볼디의 단축URL 서비스와 무관하며, 웹 사이트를 운영하는 모든 사람들을 대상으로 합니다.
귀하의 웹 사이트에 방문한 사용자에게 푸시 메시지를 전송하기 위해서는 사용자가 귀하의 웹 사이트에 대한 알림 권한에 동의해야 합니다.
사용자가 알림 권한에 거부할 경우 푸시 메시지를 전송할 수 없습니다.
본 API를 이용하면 웹 사이트에 방문했을 때 웹 브라우저에서 알림 권한에 대한 팝업 창을 표시합니다.
사용자가 알림 권한에 동의하면 대시보드의 "푸시 메시지 -> 웹사이트 푸시 발송" 페이지에 알림 데이타가 목록에 표시됩니다.
만약, 100명의 사용자가 귀하의 웹 사이트에서 알림 권한에 동의했다면 100개의 데이타가 목록에 표시됩니다.
대시보드에서 푸시 메시지를 전송하면 목록에 표시되는 모든 사용자에게 메시지가 전송됩니다.
비볼디에서 제공하는 SDK 적용은 제한없이 누구나 할 수 있으며 푸시 메시지를 전송하기 위해서는 금액이 충전되어 있어야 합니다.
푸시 메시지 전송 건당 10원이며 월 정액제를 신청하시면 무제한 발송이 가능합니다.
귀하의 웹 사이트 페이지에 비볼디에서 제공하는 스크립트를 <head>...</head> 사이에 추가하기만 하면 됩니다.
<html>
<head>
<title>샘플 페이지</title>
<script src="https://opencdn.vivoldi.com/js/webpush.min.js?ver=202404201" type="text/javascript"></script>
<script>
const apiKey = 'oc3w9m4ytso9mv5e8yse9XXXXXXXXXX'; // 귀하의 API Key
const publicKey = 'XXXXXYTRlpG8mXXXXXiuBZ6BtjyOfgPsDArFYWF2PxZbY4egmDNias1gEfN_5wftScr39K8BbcjXXXXX'; // "푸시 메시지 -> 도메인 관리" 페이지에서 등록한 도메인의 Public Key
const params = {apiKey:apiKey, publicKey:publicKey, callback:function(successful){
if (!successful) { // 알림 권한 동의에 실패한 경우...
if (Notification.permission === 'denied') { // 사용자가 알림 권한을 거부하거나 웹 브라우저에서 차단한 경우...
}
}
});
if (!webpush.checkPermission(params)) { // 사용자가 알림 권한에 동의하지 않았다면...
webpush.register(params); // 알림 권한 팝업 창 띄우기
}
</script>
</head>
<body>
.
.
.
</body>
</html>
웹 페이지 로드 시 스크립트가 즉시 실행되면 웹 브라우저에서 알림 권한 팝업 창을 표시하지 않고 차단할 확율이 높습니다.
따라서 버튼의 onclick 이벤트에 해당 스크립트를 삽입하는 것을 추천드립니다.