curl --request PUT \
--url https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"expiration_type": "seven_days",
"expiration_date": "2026-08-21T10:00:00.000Z"
}
'import requests
url = "https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link"
payload = {
"expiration_type": "seven_days",
"expiration_date": "2026-08-21T10:00:00.000Z"
}
headers = {
"X-Api-Key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {'X-Api-Key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({expiration_type: 'seven_days', expiration_date: '2026-08-21T10:00:00.000Z'})
};
fetch('https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'expiration_type' => 'seven_days',
'expiration_date' => '2026-08-21T10:00:00.000Z'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link"
payload := strings.NewReader("{\n \"expiration_type\": \"seven_days\",\n \"expiration_date\": \"2026-08-21T10:00:00.000Z\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("X-Api-Key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link")
.header("X-Api-Key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"expiration_type\": \"seven_days\",\n \"expiration_date\": \"2026-08-21T10:00:00.000Z\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["X-Api-Key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"expiration_type\": \"seven_days\",\n \"expiration_date\": \"2026-08-21T10:00:00.000Z\"\n}"
response = http.request(request)
puts response.read_body{
"unlisted_link": {
"url": "https://example.neetokb.com/public/p-1a2b3c4d5e",
"enabled": true,
"expiration_type": "never",
"expiration_date": "2026-08-21T10:00:00.000Z"
}
}{
"error": "Article must be published before an unlisted link can be generated."
}Regenerate unlisted link
This API allows to generate a fresh unlisted link for the article, replacing any existing one. The previous URL stops working immediately.
curl --request PUT \
--url https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"expiration_type": "seven_days",
"expiration_date": "2026-08-21T10:00:00.000Z"
}
'import requests
url = "https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link"
payload = {
"expiration_type": "seven_days",
"expiration_date": "2026-08-21T10:00:00.000Z"
}
headers = {
"X-Api-Key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {'X-Api-Key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({expiration_type: 'seven_days', expiration_date: '2026-08-21T10:00:00.000Z'})
};
fetch('https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'expiration_type' => 'seven_days',
'expiration_date' => '2026-08-21T10:00:00.000Z'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link"
payload := strings.NewReader("{\n \"expiration_type\": \"seven_days\",\n \"expiration_date\": \"2026-08-21T10:00:00.000Z\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("X-Api-Key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link")
.header("X-Api-Key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"expiration_type\": \"seven_days\",\n \"expiration_date\": \"2026-08-21T10:00:00.000Z\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{your-subdomain}.neetokb.com/api/external/v2/articles/{article_id}/unlisted_link")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["X-Api-Key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"expiration_type\": \"seven_days\",\n \"expiration_date\": \"2026-08-21T10:00:00.000Z\"\n}"
response = http.request(request)
puts response.read_body{
"unlisted_link": {
"url": "https://example.neetokb.com/public/p-1a2b3c4d5e",
"enabled": true,
"expiration_type": "never",
"expiration_date": "2026-08-21T10:00:00.000Z"
}
}{
"error": "Article must be published before an unlisted link can be generated."
}{your-subdomain} with your workspace’s subdomain. Learn how to find your subdomain in Workspace subdomain.
Headers
Use the X-Api-Key header to provide your workspace API key. Refer to Authentication for more information.
Path Parameters
Unique identifier of the article. Can be the article's slug, permalink, or ID. Refer to Getting the Article ID section for detailed instructions.
Body
How the link should expire. Defaults to "never". For "one_day", "seven_days", or "thirty_days", the expiration date is computed automatically. Use "custom" together with expiration_date for an exact expiration time.
never, one_day, seven_days, thirty_days, custom "seven_days"
Exact expiration date and time. Must be in the future. Required when expiration_type is "custom"; providing it together with any other expiration_type is rejected. If provided without expiration_type, expiration_type is treated as "custom".
"2026-08-21T10:00:00.000Z"
Response
OK - Request succeeded
Hide child attributes
Hide child attributes
"https://example.neetokb.com/public/p-1a2b3c4d5e"
true
never, one_day, seven_days, thirty_days, custom "never"
"2026-08-21T10:00:00.000Z"