Base URL: https://spoo.me
This endpoint is used to shorten a URL. The request payload must contain the URL to be shortened. The response contains the shortened URL.
Endpoint: POST /
The following data parameters that the API understands:
Payload | Data Type | Description | Required |
---|---|---|---|
url | String | The long URL to be shortened. | Yes |
alias | String | Custom alias for the shortened URL. | No |
password | String | Password to access the shortened URL. | No |
max-clicks | Integer | Maximum number of clicks allowed for the shortened URL. | No |
block-bots | Boolean | Whether to block bots from accessing the shortened URL. | No |
Note: password must be atleast 8 characters long
, must contain
atleast a letter
and a number
and a special character
either '@' or '.'
and cannot be consecutive
.
The following headers are used in the API requests and responses:
Header | Value |
---|---|
Accept * |
application/json |
Content-Type * |
application/x-www-form-urlencoded |
Note: Both of the above headers are compuslary
import requests
import json
url = "https://spoo.me"
# Replace these with your actual values
payload = {
"url": "https://example.com",
"alias": "example", # you can choose any other alias
"max-clicks": 10,
"password": "SuperStrongPassword@18322"
}
# Necessary to get a non-html response
headers = {
"Accept": "application/json"
}
response = requests.post(url, data=payload, headers=headers)
if response.status_code == 200:
# If the request was successful, print the shortened URL
shortened_url = response.json()
else:
# If the request failed, print the error message
print(f"Error: {response.status_code}")
print(response.text)
Response:
{"short_url": "https://spoo.me/example"}
const axios = require('axios');
const data = {
url: 'https://example.com',
alias: 'node-exampl',
password: 'NodeIsCool@Example2',
'max-clicks': '200'
};
axios.post('https://spoo.me/', data, {
headers: {
'content-type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
},
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.error(error);
});
Response:
{"short_url": "https://spoo.me/node-exampl"}
using System.Net.Http;
using System.Net.Http.Headers;
using System.Collections.Generic;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://spoo.me/"),
Headers =
{
{ "Accept", "application/json" },
},
Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "url", "https://example.com" }, { "alias", "cSharpExa" }, { "password", "HelloC_sharp1@" }, { "max-clicks", "200" }
}),
};
try
{
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
}
catch (HttpRequestException ex)
{
Console.WriteLine($"HTTP request error: {ex.Message}");
}
Response:
{"short_url": "https://spoo.me/cSharpExa"}
const url = 'https://spoo.me/';
const data = new URLSearchParams();
data.append('url', 'https://example.com');
data.append('alias', 'jsExample1');
data.append('password', 'jsIsAlsoCool@12');
data.append('max-clicks', '200');
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Accept', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log(xhr.responseText);
} else {
console.error(`HTTP error! Status: ${xhr.status}`);
}
}
};
xhr.send(data);
Response:
{"short_url": "https://spoo.me/jsExample1"}
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class HttpRequestExample {
public static void main(String[] args) {
// Define the URL
String url = "https://spoo.me/";
// Define the Long URL
String longUrl = "https://example.com";
// Encode the Long URL
String encodedLongUrl = URLEncoder.encode(longUrl, StandardCharsets.UTF_8);
// Build the request body
String requestBody = "url="+encodedLongUrl+"&alias=JavaIsHard&password=JavaHardNGL@1000&max-clicks=200";
// Create and configure the HttpClient
HttpClient httpClient = HttpClient.newHttpClient();
// Build the HttpRequest
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
try {
// Send the request and receive the response
HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// Print the response status code and body
System.out.println("Response Code: " + response.statusCode());
System.out.println("Response Body: " + response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Response:
{"short_url": "https://spoo.me/JavaIsHard"}
package main
import (
"context"
"fmt"
"io"
"net"
"net/http"
"net/url"
"strings"
"time"
)
func main() {
// Set DNS resolver to use Google's public DNS server
net.DefaultResolver = &net.Resolver{
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{Timeout: 500 * time.Millisecond}
return d.DialContext(ctx, "udp", "8.8.8.8:53")
},
}
apiUrl := "https://spoo.me/"
longUrl := "https://example.com"
encodedLongUrl := url.QueryEscape(longUrl)
payload := strings.NewReader("url="+encodedLongUrl+"&alias=GoExample&max-clicks=200&password=GoIsNew@Yes5")
req, err := http.NewRequest("POST", apiUrl, payload)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println(res)
fmt.Println(string(body))
}
Response:
{"short_url": "https://spoo.me/GoExample"}
require 'uri'
require 'net/http'
url = URI("https://spoo.me")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
longUrl = "https://example.com"
encodedLongUrl = URI.encode_www_form_component(longUrl)
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/x-www-form-urlencoded'
request["Accept"] = 'application/json'
request.body = "url=#{encodedLongUrl}&alias=RubyIsRuby&password=FHVygyg@132o&max-clicks=200"
response = http.request(request)
puts response.read_body
Response:
{"short_url": "https://spoo.me/RubyIsRuby"}
/get-code
command of our official discord-bot,
spooBot
🤖
This section provides information about the various errors that could occur while making requests through this endpoint.
Error Name | Code | Description |
---|---|---|
UrlError | 400 | The request does not contain the long URL or contains an invalid url. The url must contain a
valid protocol like https , http and must follow rfc-1034 &
rfc-2727
|
AliasError | 400 | The User requested Alias is invalid or already taken. The alias must be
alphanumeric & must
be under 15 chars , anything beyond 15 chars would be stripped by the API
|
PasswordError | 400 | The user entered password must be atleast 8 characters long , must contain
atleast a letter and a number and a special character
either '@' or '.' and cannot be consecutive . |
MaxClicksError | 400 | The user entered max-clicks is not a positive integer . |
Endpoint: POST /emoji
The following data parameters that the API understands:
Payload | Data Type | Description | Required |
---|---|---|---|
url | String | The long URL to be shortened. | Yes |
emojies | String | Custom emojies sequence for the shortened URL. Must contain
only emojies , no other character is allowed.
|
No |
password | String | Password to access the shortened URL. | No |
max-clicks | Integer | Maximum number of clicks allowed for the shortened URL. | No |
block-bots | Boolean | Whether to block bots from accessing the shortened URL. | No |
Note: password must be atleast 8 characters long
, must contain
atleast a letter
and a number
and a special character
either '@' or '.'
and cannot be consecutive
.
The following headers are used in the API requests and responses:
Header | Value |
---|---|
Accept * |
application/json |
Content-Type * |
application/x-www-form-urlencoded |
Note: Both of the above headers are compuslary
import requests
url = "https://spoo.me/emoji/"
payload = {
"url": "https://example.com",
"alias": "🐍🐍",
"password": 1000,
"max-clicks": "Python.Snake63"
}
headers = {
"Accept": "application/json",
}
response = requests.post(url, data=payload, headers=headers)
if response.status_code == 200:
print(response.json())
else:
print(response.text)
Response:
{"short_url": "https://spoo.me/🐍🐍"}
const axios = require('axios');
const data = {
url: 'https://example.com/emoji/',
alias: '🚀🚀',
password: 'Node.emojiIsCool1',
'max-clicks': '200'
};
axios.post('https://spoo.me/', data, {
headers: {
'content-type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
},
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.error(error);
});
Response:
{"short_url": "https://spoo.me/🚀🚀"}
using System.Net.Http;
using System.Net.Http.Headers;
using System.Collections.Generic;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://spoo.me/emoji/"),
Headers =
{
{ "Accept", "application/json" },
},
Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "url", "https://example.com" }, { "alias", "🌊#️⃣" }, { "password", "Emoji@C_sharp1" }, { "max-clicks", "200" }
}),
};
try
{
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
}
catch (HttpRequestException ex)
{
Console.WriteLine($"HTTP request error: {ex.Message}");
}
Response:
{"short_url": "https://spoo.me/🌊#️⃣"}
const url = 'https://spoo.me/emoji/';
const data = new URLSearchParams();
data.append('url', 'https://example.com');
data.append('alias', '☕📜');
data.append('password', 'jsIsAlsoCool@12');
data.append('max-clicks', '200');
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Accept', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log(xhr.responseText);
} else {
console.error(`HTTP error! Status: ${xhr.status}`);
}
}
};
xhr.send(data);
Response:
{"short_url": "https://spoo.me/☕📜"}
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class HttpRequestExample {
public static void main(String[] args) {
// Define the URL
String url = "https://spoo.me/emoji/";
// Define the Long URL
String longUrl = "https://example.com";
// Encode the Long URL
String encodedLongUrl = URLEncoder.encode(longUrl, StandardCharsets.UTF_8);
// Build the request body
String requestBody = "url="+encodedLongUrl+"&alias=☕&password=JavaHardNGL@1000&max-clicks=200";
// Create and configure the HttpClient
HttpClient httpClient = HttpClient.newHttpClient();
// Build the HttpRequest
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
try {
// Send the request and receive the response
HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// Print the response status code and body
System.out.println("Response Code: " + response.statusCode());
System.out.println("Response Body: " + response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Response:
{"short_url": "https://spoo.me/☕"}
package main
import (
"context"
"fmt"
"io"
"net"
"net/http"
"net/url"
"strings"
"time"
)
func main() {
// Set DNS resolver to use Google's public DNS server
net.DefaultResolver = &net.Resolver{
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{Timeout: 500 * time.Millisecond}
return d.DialContext(ctx, "udp", "8.8.8.8:53")
},
}
apiUrl := "https://spoo.me/emoji/"
longUrl := "https://example.com"
encodedLongUrl := url.QueryEscape(longUrl)
payload := strings.NewReader("url="+encodedLongUrl+"&alias=💨👋🏻&max-clicks=200&password=GoIsNew@Yes5")
req, err := http.NewRequest("POST", apiUrl, payload)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println(res)
fmt.Println(string(body))
}
Response:
{"short_url": "https://spoo.me/👋🏻💨"}
require 'uri'
require 'net/http'
url = URI("https://spoo.me/emoji/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
longUrl = "https://example.com"
encodedLongUrl = URI.encode_www_form_component(longUrl)
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/x-www-form-urlencoded'
request["Accept"] = 'application/json'
request.body = "url=#{encodedLongUrl}&alias=💎&password=FHVygyg@132o&max-clicks=200"
response = http.request(request)
puts response.read_body
Response:
{"short_url": "https://spoo.me/💎"}
This section provides information about the various errors that could occur while making requests through this endpoint.
Error Name | Code | Description |
---|---|---|
UrlError | 400 | The request does not contain the long URL or contains an invalid url. The url must contain a
valid protocol like https , http and must follow rfc-1034 &
rfc-2727
|
EmojiError | 400 | The User requested Emoji sequence is invalid or already taken. The emoji sequence must contain
only emojies , no other character is allowed.
|
PasswordError | 400 | The user entered password must be atleast 8 characters long , must contain
atleast a letter and a number and a special character
either '@' or '.' and cannot be consecutive . |
MaxClicksError | 400 | The user entered max-clicks is not a positive integer . |
This endpoint is used to retrieve statistics about a shortened URL. The request must contain the short code of the URL. The response contains the statistics.
Endpoint: POST /stats/{shortCode}
shortCode
can also represent the short code of an emoji URL.
The following data parameters that the API understands:
Payload | Description | Required |
---|---|---|
password | Password of the shortened url if any. | Yes, if and only if the short url is password protected. |
The following headers are used in the API requests and responses:
Header | Value |
---|---|
Content-Type * |
application/x-www-form-urlencoded |
import requests
import json
# Replace these with your actual values
short_code = "exa"
base_url = "https://spoo.me"
payload = { # not required if your short url is not password protected
"password": "Example@12"
}
# Make the request
response = requests.post(
f"{base_url}/stats/{short_code}",
data = payload
)
# Check the response
if response.status_code == 200:
# If the request was successful, print the URL statistics
url_stats = response.json()
print(json.dumps(url_stats, indent=4))
else:
# If the request failed, print the error message
print(f"Error: {response.status_code}")
print(response.text)
const axios = require('axios');
const short_code = 'exa';
const data = { // not required if your short url is not password protected
password: 'Example@12',
};
axios.post('https://spoo.me/stats/${short_code}', data, {
headers: {
'content-type': 'application/x-www-form-urlencoded',
},
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.error(error);
});
using System.Net.Http;
using System.Net.Http.Headers;
using System.Collections.Generic;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://spoo.me/stats/exa"),
Headers =
{
{ "Content-Type", "application/x-www-form-urlencoded" },
},
Content = new FormUrlEncodedContent(new Dictionary<string, string> // not required if your short url is not password protected
{
{ "password", "Example@12" }
}),
};
try
{
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
}
catch (HttpRequestException ex)
{
Console.WriteLine($"HTTP request error: {ex.Message}");
}
// define the short_code & url
const url = 'https://spoo.me/stats/exa';
const data = new URLSearchParams();
data.append('password', 'Example@12'); // not required if your short url is not password protected
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log(xhr.responseText);
} else {
console.error(`HTTP error! Status: ${xhr.status}`);
}
}
};
xhr.send(data);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpRequestExample {
public static void main(String[] args) {
// Define the short_code
String short_code = "exa";
// Define the URL
String url = "https://spoo.me/stats/"+short_code;
// Build the request body
String requestBody = "password=Example@12"; // not required if your short url is not password protected
// Create and configure the HttpClient
HttpClient httpClient = HttpClient.newHttpClient();
// Build the HttpRequest
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
try {
// Send the request and receive the response
HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// Print the response status code and body
System.out.println("Response Code: " + response.statusCode());
System.out.println("Response Body: " + response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
package main
import (
"context"
"fmt"
"io"
"net"
"net/http"
"strings"
"time"
)
func main() {
// Set DNS resolver to use Google's public DNS server
net.DefaultResolver = &net.Resolver{
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{Timeout: 500 * time.Millisecond}
return d.DialContext(ctx, "udp", "8.8.8.8:53")
},
}
short_code := "exa"
url := "https://spoo.me/stats/" + short_code
payload := strings.NewReader("password=Example@12") // not required if your short url is not password protected
req, err := http.NewRequest("POST", url, payload)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
res, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println(res)
fmt.Println(string(body))
}
require 'net/http'
short_code = "exa"
url = URI("https://spoo.me/stats/#{short_code}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/x-www-form-urlencoded'
request.body = "password=Example@12" # not required if your short url is not password protected
response = http.request(request)
puts response.read_body
Response:
{
"_id": "exa",
"average_daily_clicks": 1.0,
"average_monthly_clicks": 0.03,
"average_redirection_time": 263.04,
"average_weekly_clicks": 0.14,
"block-bots": false,
"bots": {
"Googlebot": 1
},
"browser": {
"Edge": 1
},
"counter": {
"2023-12-18": 1
},
"country": {
"France": 1
},
"creation-date": "2023-12-18",
"expired": null,
"last-click": "2023-12-18 22:06:02.298005+00:00",
"last-click-browser": "Edge",
"last-click-os": "Windows",
"max-clicks": null,
"os_name": {
"Windows": 1
},
"password": "Example@12",
"referrer": {
"spoo.me": 1
},
"short_code": "exa",
"total-clicks": 1,
"total_unique_clicks": 1,
"unique_browser": {
"Edge": 1
},
"unique_counter": {
"2023-12-18": 1
},
"unique_country": {
"France": 1
},
"unique_os_name": {
"Windows": 1
},
"unique_referrer": {
"spoo.me": 1
},
"url": "https://example.com"
}
The response contains the following data:
Key | Data Type | Description |
---|---|---|
_id | Str | The Short Code of the Short Link. |
average_daily_clicks | Float | Average Clicks per day since the link was created. |
average_monthly_clicks | Float | Average Clicks per month since the link was created. |
average_weekly_clicks | Float | Average Clicks per week since the link was created. |
average_redirection_time | Float | Average Redirection Time of the Short Link in milliseconds. |
block-bots | Bool | Tells whether the Bots are blocked from accessing the Short Link. |
bots | Dict | Data about the Bots in which the short link was accessed. |
browser | Dict | Data about the Browsers in which the short link was accessed. |
creation-date | Str | Date when the short link was created. |
counter | Dict | Data about the clicks per day since the link was created. |
country | Dict | Data about the Countries in which the short link was accessed. |
expired* | Bool | Tells whether the link has expired or not. |
last-click | Str | Last Time when the short link was accessed. |
last-click-browser | Str | Last Browser in which the short link was accessed. |
last-click-os | Str | Last Os name in which the short link was accessed. |
max-clicks* | Str | Information about the Max Clicks set my the User on the Short Link. |
os_name | Dict | Data about the Os names in which the short link was accessed. |
password* | Str | The password set by the User on the Short Link. |
short_code | Str | The Short Code of the Short Link. |
total-clicks | Int | Count of the total clicks made since the short link was created. |
total_unique_clicks | Int | Count of the total unique clicks made since the short link was created. |
unique_browser | Dict | Data about the Unique Browsers in which the short link was accessed. |
unique_counter | Dict | Data about the Unique clicks per day since the link was created. |
unique_country | Dict | Data about the Unique Countries in which the short link was accessed. |
unique_os_name | Dict | Data about the Unique Os names in which the short link was accessed. |
unique_referrer | Dict | Data about the Unique Referrers in which the short link was accessed. |
url | Str | Original Long Url which the short link redirects to. |
* Null if the Short link didnt have max-clicks set or was not password protected.
This section provides information about the various errors that could occur while making requests through the API.
Error Name | Code | Description |
---|---|---|
UrlError |
404 | The user requested Url never existed. |
PasswordError |
400 | The user entered password is invalid. |
This endpoint is used to export the data of your shortened URL. The request must contain the short code of the URL along with the format in which you want to recieve your data. The response contains the data of the shortened URL.
Endpoint: POST /export/{shortCode}/{exportFormat}
shortCode
can also represent the short code of an emoji URL.
The following export formats are available:
Format | Description |
---|---|
json | Export the data in JSON format. |
csv | Export the data in CSV format. The API will return the data divided in many files zipped together. |
xlsx | Export the data in XLSX (Excel file) format. |
xml | Export the data in XML format. |
You can choose anyone of these formats and pass it in the request parameter
Important Note
: The API returns raw data in the specified format, which you may need to
store in a file.
The following data parameters that the API understands:
Payload | Description | Required |
---|---|---|
password | Password of the shortened url if any. | Yes, if and only if the short url is password protected. |
The following headers are used in the API requests and responses:
Header | Value |
---|---|
Content-Type * |
application/x-www-form-urlencoded |
import requests
import json
# Replace these with your actual values
short_code = "exa"
base_url = "https://spoo.me"
export_format = "xlsx" # You can choose from ["json", "csv", "xlsx", "xml"]
payload = { # not required if your short url is not password protected
"password": "Example@12"
}
# Make the request
response = requests.post(
f"{base_url}/export/{short_code}/{export_format}",
data = payload
)
# Check the response
if response.status_code == 200:
# If the request was successful, store the data in a file
with open(f"{short_code}.{export_format}", "wb") as file: # Note if the export format is csv, the file will be a zip file
file.write(response.content)
else:
# If the request failed, print the error message
print(f"Error: {response.status_code}")
print(response.text)
const axios = require("axios");
const fs = require("fs");
const querystring = require("querystring");
// Replace these with your actual values
const short_code = "exa";
const base_url = "https://spoo.me";
const export_format = "xlsx"; // You can choose from ["json", "csv", "xlsx", "xml"]
const payload = {
// not required if your short url is not password protected
password: "Example@12",
};
// Make the request
axios
.post(
`${base_url}/export/${short_code}/${export_format}`,
querystring.stringify(payload), // Convert the object to a URL-encoded string
{
responseType: "arraybuffer",
headers: {
"content-type": "application/x-www-form-urlencoded", // Specify the content type
},
}
)
.then((response) => {
// If the request was successful, store the data in a file
fs.writeFile(`${short_code}.${export_format}`, response.data, (err) => { // Note if the export format is csv, the file will be a zip file
if (err) {
console.error(err);
} else {
console.log("File saved successfully");
}
});
})
.catch((error) => {
// If the request failed, print the error message
console.error(`Error: ${error.response.status}`);
console.error(error.response.data.toString());
});
// Import HttpClient module
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
// Replace these with your actual values
const string short_code = "exa";
const string base_url = "https://spoo.me";
const string export_format = "xlsx"; // You can choose from ["json", "csv", "xlsx", "xml"]
// Create an instance of HttpClient
var client = new HttpClient();
// Set the content
var content = new FormUrlEncodedContent(new Dictionary // not required if your short url is not password protected
{
{ "password", "Example@12" }
});
// Make the request
var response = await client.PostAsync($"{base_url}/export/{short_code}/{export_format}", content); // Note if the export format is csv, the file will be a zip file
// Check the response
if (response.IsSuccessStatusCode)
{
// If the request was successful, store the data in a file
var data = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes($"{short_code}.{export_format}", data);
Console.WriteLine("File saved successfully");
}
else
{
// If the request failed, print the error message
Console.WriteLine($"Error: {response.StatusCode}");
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
// Create a new XMLHttpRequest object
var xhr = new XMLHttpRequest();
// Replace these with your actual values
var short_code = "exa";
var base_url = "https://spoo.me";
var export_format = "xlsx"; // You can choose from ["json", "csv", "xlsx", "xml"]
var payload = new FormData(); // not required if your short url is not password protected
payload.append("password", "Example@12");
// Open a connection by specifying the request type and endpoint
xhr.open("POST", `${base_url}/export/${short_code}/${export_format}`, true);
// Set the response type to blob or arraybuffer
xhr.responseType = "blob"; // or "arraybuffer"
// Send the request
xhr.send(payload);
// Listen to xhr events for response
xhr.onload = function () {
// If the request was successful, store the data in a file
if (xhr.status == 200) {
var data = xhr.response;
var blob = new Blob([data], { type: "application/octet-stream" });
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = `${short_code}.${export_format}`; // Note if the export format is csv, the file will be a zip file
a.click();
window.URL.revokeObjectURL(url);
console.log("File saved successfully");
} else {
// If the request failed, print the error message
console.error(`Error: ${xhr.status}`);
console.error(xhr.responseText);
}
};
// Import java.net.http package
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;
public class ExportExample {
public static void main(String[] args) {
// Define the URL
String short_code = "exa";
String base_url = "https://spoo.me";
String export_format = "csv"; // You can choose from ["json", "csv", "xlsx", "xml"]
// Create a map for form data
Map
package main
import (
"context"
"fmt"
"io"
"net"
"net/http"
"strings"
"time"
"os"
"net/url"
)
func main() {
// Set DNS resolver to use Google's public DNS server
net.DefaultResolver = &net.Resolver{
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{Timeout: 500 * time.Millisecond}
return d.DialContext(ctx, "udp", "8.8.8.8:53")
},
}
base_url := "https://spoo.me"
short_code := "exa"
export_format := "xlsx" // You can choose from ["json", "csv", "xlsx", "xml"]
// Create a form data with the password (not required if your short url is not password protected)
formData := url.Values{}
formData.Set("password", "Example@12")
// Convert the form data to a URL-encoded string
payload := formData.Encode()
req, err := http.NewRequest("POST", base_url+"/export/"+short_code+"/"+export_format, strings.NewReader(payload))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
res, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer res.Body.Close()
if res.StatusCode == 200 {
// If the request was successful, store the data in a file
file, err := os.Create(short_code + "." + export_format) // Note if the export format is csv, the file will be a zip file
if err != nil {
fmt.Println("Error creating file:", err)
return
}
defer file.Close()
_, err = io.Copy(file, res.Body)
if err != nil {
fmt.Println("Error copying data to file:", err)
return
}
fmt.Println("File saved successfully")
} else {
// If the request failed, print the error message
fmt.Println("Error:", res.StatusCode)
body, err := io.ReadAll(res.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
fmt.Println(string(body))
}
}
require 'net/http'
short_code = "exa"
base_url = "https://spoo.me"
export_format = "xlsx" # You can choose from ["json", "csv", "xlsx", "xml"]
url = URI("#{base_url}/export/#{short_code}/#{export_format}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/x-www-form-urlencoded'
request.body = "password=Example@12" # not required if your short url is not password protected
response = http.request(request)
File.open("#{short_code}.#{export_format}", "w") do |file| # Note if the export format is csv, the file will be a zip file
file.write(response.read_body)
puts "File saved successfully"
end
Response:
The API returns raw data in the specified format, which you may need to store in a file.
This section provides information about the various errors that could occur while making requests through the API.
Error Name | Code | Description |
---|---|---|
UrlError |
404 | The user requested Url (short_code) never existed. |
PasswordError |
400 | The user entered password is invalid. |
FormatError |
400 | The user entered an invalid export format. The Exportformat must either xml, xlsx, json or csv |
Note: If you're exporting your data in CSV format, ensure you save the file with a .zip
extension, not .csv
. Failure to do so may result in logical errors in your code. You need
to save it in a zip file because the API returns the data divided in many files zipped
together.
Spoo.me API has a rate limit of 5 requests per minute
, 50 requests per hour
and
500 requests per day
for the POST /
, POST /emoji
endpoints. If you
exceed
this limit, you will receive a 429
status code in response to your requests.
Spoo.me has a Python library that makes it easy to use the Spoo.me API. You can install it using pip:
pip install py_spoo_url
Once installed, you can use the library to shorten URLs, get the stats of a shortened URL, and export the data of a shortened URL.
Here's a quick example of how to shorten a URL:
from py_spoo_url import Shorten, Statistics
shortener = Shortener()
long_url = "https://www.example.com"
short_url = shortener.shorten(long_url, password="SuperSecretPassword@444", max_clicks=100)
# for custom alias, put `alias=<your_choice>`
print(f"Shortened URL: {short_url}")
Complete documentation for the library can be found here.
SpooBot is a Discord bot that uses the Spoo.me API. It provides the following features:
/shorten
command to shorten URLs./stats
command to get the stats of a shortened URL and export its data./get-code
command to get the code to shorten URLs in various languages.SpooBot is available on the Discord Bot List. You can add it to your server by clicking here.
SpooBot is also open source. You can find the source code on GitHub.
Spoo.me API is a powerful tool that allows you to shorten URLs, get the stats of a shortened URL, and export the data of a shortened URL. It's easy to use and provides a lot of flexibility. We hope this guide has helped you understand how to use the API and how to integrate it into your applications.
If you have any questions or need further assistance, feel free to reach out to us at
support@spoo.me
or you can join our official
Discord Server
. We're
always happy to help!