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.

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

How to call the API

Request:
Host: https://vivoldi.com/api HTTP/1.1
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
Simply add Authorisation, Content-type to your Http Header and call the API.
Response:
{
    "code": 0,
    "message": "",
    "result": Object
}
code - The response code, where 0 is success and any other value is a failure code.
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.
Please contact Vivoldi if you need REST API improvements or modifications.

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.

Request:
Post /api/link/v1/create HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
Request:
FieldsField DescriptionsDescriptionRequiredType
urlLong URLsThe long URL to be redirected to when the generated short link is clicked.string
domainDomain 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
grpIdxGroup 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
brandLinkIdBrand 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
ttlLink Title If the value is empty, it is automatically saved as the webpage title of the long link. string
memoNotes You can set additional information that you need for administration without exposing it to users. string
notfSubscYnPush 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
clksIpFilteringYnIP 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
pushNotifyYnPush 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
mailNotifyYnMail 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
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">
	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();
		}
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":"",
    "result":"https://vvd.bz/jH3d"
}
Response:
FieldsDescriptionType
codeResponse code (0:Success)int
messageThe response message, or a related message if the response code is non-zero.string
resultResponse value (shortened link)string

Edit a link

Edit the short link you created.

Request:
Post /api/link/v1/edit HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
Request:
FieldsField DescriptionsDescriptionRequiredType
linkIdLink 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
domainDomain 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
grpIdxGroup ID Change the group of the generated link.
To find out the group ID, you need to call the "Group list" API.
int
ttlLink title If the value is empty, the link title is not modified. string
memoNotes You can set additional information for administration without exposing it to users.
If the value is empty, the note will not be modified.
string
notfSubscYnPush 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
pushNotifyYnPush 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
mailNotifyYnMail 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
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">
	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();
		}
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":""
}
Response:
FieldsDescriptionType
codeResponse code (0:Success)int
messageThe response message, or a related message if the response code is non-zero.string

Delete a link

Delete the short link you created.

Request:
Post /api/link/v1/remove HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
Request:
FieldsField DescriptionsDescriptionRequiredType
linkIdLink 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
domainDomain 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
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">
	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();
		}
	}
}
Response:
HTTP/1.1 200 OK
Content-type: application/json;charset=UTF-8
{
    "code":0,
    "message":""
}
Response:
FieldsDescriptionType
codeResponse code (0:Success)int
messageThe response message, or a related message if the response code is non-zero.string

Group List

Gets a list of created link groups.

Request:
Post /api/group/v1/list HTTP/1.1
Host: https://vivoldi.com
Authorization: APIKey {Your API Key}
Content-type: application/x-www-form-urlencoded
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">
	그룹 이름: <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();
		}
	}
}
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

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 ... and easily validate with just one line of code.

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>
Request:
Post /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">
	링크 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();
		}
	}
}
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는 비볼디의 단축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 이벤트에 해당 스크립트를 삽입하는 것을 추천드립니다.