curl --request POST \
--url https://api.h0p.co/domain \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"domain": "links.example.com"
}
'import requests
url = "https://api.h0p.co/domain"
payload = { "domain": "links.example.com" }
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({domain: 'links.example.com'})
};
fetch('https://api.h0p.co/domain', 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://api.h0p.co/domain",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'domain' => 'links.example.com'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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://api.h0p.co/domain"
payload := strings.NewReader("{\n \"domain\": \"links.example.com\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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.post("https://api.h0p.co/domain")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"domain\": \"links.example.com\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.h0p.co/domain")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"domain\": \"links.example.com\"\n}"
response = http.request(request)
puts response.read_body{
"id": "01933eb8-541f-7000-a9f4-e4eee80ff04e",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-16T14:20:00Z",
"organizationId": "01933eb8-541f-7000-a9f4-e4eee80ff04e",
"domain": "links.example.com",
"isActive": true,
"lastCheckedAt": "2024-01-15T10:35:00Z",
"isVerified": true,
"txtRecord": "_vercel=1234567890abcdef",
"isPrimary": true,
"qrCodeId": "01933eb8-541f-7000-a9f4-e4eee80ff04e",
"fallbackUrl": "https://example.com/404",
"appleAppSiteAssociation": {},
"androidAssetLinks": {},
"qrCode": {
"options": {
"data": "https://example.com/abc123",
"type": "svg",
"width": 300,
"height": 300,
"margin": 4,
"image": "https://example.com/logo.png",
"imageOptions": {
"hideBackgroundDots": true,
"imageSize": 0.4,
"crossOrigin": "anonymous",
"margin": 10
},
"dotsOptions": {
"type": "rounded",
"color": "#000000",
"gradient": {
"type": "linear",
"colorStops": [
{
"offset": 0,
"color": "#3B82F6"
},
{
"offset": 1,
"color": "#8B5CF6"
}
],
"rotation": 45
},
"roundSize": true
},
"cornersSquareOptions": {
"type": "square",
"color": "#3B82F6",
"gradient": {
"type": "linear",
"colorStops": [
{
"offset": 0,
"color": "#3B82F6"
},
{
"offset": 1,
"color": "#8B5CF6"
}
],
"rotation": 45
}
},
"cornersDotOptions": {
"type": "dot",
"color": "#8B5CF6",
"gradient": {
"type": "linear",
"colorStops": [
{
"offset": 0,
"color": "#3B82F6"
},
{
"offset": 1,
"color": "#8B5CF6"
}
],
"rotation": 45
}
},
"backgroundOptions": {
"round": 0.1,
"color": "#FFFFFF"
}
},
"imageId": "01933eb8-541f-7000-a9f4-e4eee80ff04e"
}
}{
"code": "PLAN_LIMIT_REACHED",
"message": "You have reached the maximum number of domains for your plan."
}{
"code": "ALREADY_EXIST"
}Create custom domain
Add custom domain for short links. DNS verification required. First domain becomes primary. QR code template auto-created.
curl --request POST \
--url https://api.h0p.co/domain \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"domain": "links.example.com"
}
'import requests
url = "https://api.h0p.co/domain"
payload = { "domain": "links.example.com" }
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({domain: 'links.example.com'})
};
fetch('https://api.h0p.co/domain', 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://api.h0p.co/domain",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'domain' => 'links.example.com'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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://api.h0p.co/domain"
payload := strings.NewReader("{\n \"domain\": \"links.example.com\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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.post("https://api.h0p.co/domain")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"domain\": \"links.example.com\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.h0p.co/domain")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"domain\": \"links.example.com\"\n}"
response = http.request(request)
puts response.read_body{
"id": "01933eb8-541f-7000-a9f4-e4eee80ff04e",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-16T14:20:00Z",
"organizationId": "01933eb8-541f-7000-a9f4-e4eee80ff04e",
"domain": "links.example.com",
"isActive": true,
"lastCheckedAt": "2024-01-15T10:35:00Z",
"isVerified": true,
"txtRecord": "_vercel=1234567890abcdef",
"isPrimary": true,
"qrCodeId": "01933eb8-541f-7000-a9f4-e4eee80ff04e",
"fallbackUrl": "https://example.com/404",
"appleAppSiteAssociation": {},
"androidAssetLinks": {},
"qrCode": {
"options": {
"data": "https://example.com/abc123",
"type": "svg",
"width": 300,
"height": 300,
"margin": 4,
"image": "https://example.com/logo.png",
"imageOptions": {
"hideBackgroundDots": true,
"imageSize": 0.4,
"crossOrigin": "anonymous",
"margin": 10
},
"dotsOptions": {
"type": "rounded",
"color": "#000000",
"gradient": {
"type": "linear",
"colorStops": [
{
"offset": 0,
"color": "#3B82F6"
},
{
"offset": 1,
"color": "#8B5CF6"
}
],
"rotation": 45
},
"roundSize": true
},
"cornersSquareOptions": {
"type": "square",
"color": "#3B82F6",
"gradient": {
"type": "linear",
"colorStops": [
{
"offset": 0,
"color": "#3B82F6"
},
{
"offset": 1,
"color": "#8B5CF6"
}
],
"rotation": 45
}
},
"cornersDotOptions": {
"type": "dot",
"color": "#8B5CF6",
"gradient": {
"type": "linear",
"colorStops": [
{
"offset": 0,
"color": "#3B82F6"
},
{
"offset": 1,
"color": "#8B5CF6"
}
],
"rotation": 45
}
},
"backgroundOptions": {
"round": 0.1,
"color": "#FFFFFF"
}
},
"imageId": "01933eb8-541f-7000-a9f4-e4eee80ff04e"
}
}{
"code": "PLAN_LIMIT_REACHED",
"message": "You have reached the maximum number of domains for your plan."
}{
"code": "ALREADY_EXIST"
}Authorizations
API Key authentication for programmatic access.
How to use:
- Create an API key from your dashboard settings
- Include the key in the
x-api-keyheader with each request - API keys have granular permissions (domains, shortLinks, files, stats, apiKeys)
Example:
curl -H "x-api-key: your-api-key-here" https://api.h0p.co/short-link/list
Types of API keys:
- User keys: Linked to your user account (one per organization)
- Bot keys: Autonomous machine users (one per organization)
Security notes:
- Keep your API keys secure and never commit them to version control
- API keys cannot access authentication endpoints (/auth/*)
- Keys can be revoked at any time from the dashboard
Body
Domain name to add (e.g., links.example.com)
Domain creation request
Custom domain name for short links
1"links.example.com"
Response
Domain created successfully. Use DNS check endpoint to verify ownership.
Complete domain object with all fields
Domain UUID
"01933eb8-541f-7000-a9f4-e4eee80ff04e"
Creation timestamp
"2024-01-15T10:30:00Z"
Last update timestamp
"2024-01-16T14:20:00Z"
Organization UUID
"01933eb8-541f-7000-a9f4-e4eee80ff04e"
Domain name
"links.example.com"
Whether domain is active
true
Last DNS check timestamp
"2024-01-15T10:35:00Z"
Complete verification status
true
TXT record value for DNS verification
"_vercel=1234567890abcdef"
Primary domain status
true
QR code template UUID
"01933eb8-541f-7000-a9f4-e4eee80ff04e"
Fallback URL for 404s
"https://example.com/404"
Apple Universal Links config
Show child attributes
Show child attributes
Android App Links config
Show child attributes
Show child attributes
Default QR code template
Show child attributes
Show child attributes