TypeScript client
import { OctosparkClient } from '@octospark/sdk'
const client = new OctosparkClient({
token: process.env.OCTOSPARK_TOKEN
})
const response = await client.shortlinks.getClicksByDimension({
teamId: process.env.OCTOSPARK_TEAM_ID ?? "teamId",
id: process.env.OCTOSPARK_ID ?? "id",
query: {
"groupBy": process.env.OCTOSPARK_GROUP_BY ?? "groupBy",
},
})import os
from octospark_sdk import OctosparkClient
client = OctosparkClient(token=os.environ["OCTOSPARK_TOKEN"])
response = client.shortlinks.get_clicks_by_dimension(
teamId=os.environ.get("OCTOSPARK_TEAM_ID", "teamId"),
id=os.environ.get("OCTOSPARK_ID", "id"),
query={
"groupBy": os.environ.get("OCTOSPARK_GROUP_BY", "groupBy"),
}
)octospark shortlinks get-clicks-by-dimension \
--request '{"path":{"teamId":"teamId","id":"id"},"query":{"groupBy":"groupBy","from":"from","to":"to"}}'use reqwest::Client;
use std::env;
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new();
let base_url = env::var("OCTOSPARK_API_URL").unwrap_or_else(|_| "https://api.octospark.ai".to_string());
let team_id = env::var("OCTOSPARK_TEAM_ID").unwrap_or_else(|_| "teamId".to_string());
let id = env::var("OCTOSPARK_ID").unwrap_or_else(|_| "id".to_string());
let group_by = env::var("OCTOSPARK_GROUP_BY").unwrap_or_else(|_| "groupBy".to_string());
let url = format!("{}/v1/teams/{}/shortlinks/{}/clicks", base_url.trim_end_matches('/'), team_id, id);
let token = env::var("OCTOSPARK_TOKEN").expect("OCTOSPARK_TOKEN");
let mut request = client.get(url).bearer_auth(token);
let query = [("groupBy", group_by.as_str())];
request = request.query(&query);
let response = request.send().await?;
println!("{}", response.text().await?);
Ok(())
}import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
Future<void> main() async {
final baseUrl = Platform.environment['OCTOSPARK_API_URL'] ?? 'https://api.octospark.ai';
final token = Platform.environment['OCTOSPARK_TOKEN'];
final teamId = Platform.environment['OCTOSPARK_TEAM_ID'] ?? 'teamId';
final id = Platform.environment['OCTOSPARK_ID'] ?? 'id';
final groupBy = Platform.environment['OCTOSPARK_GROUP_BY'] ?? 'groupBy';
final url = '${baseUrl.replaceFirst(RegExp(r'/$'), '')}/v1/teams/$teamId/shortlinks/$id/clicks';
final uri = Uri.parse(url).replace(queryParameters: {
'groupBy': groupBy,
});
final headers = {
'Authorization': 'Bearer $token',
};
final response = await http.get(
uri,
headers: headers,
);
print(response.body);
}curl --request GET \
--url https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks \
--header 'Authorization: Bearer <token>'<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body$headers=@{}
$headers.Add("Authorization", "Bearer <token>")
$response = Invoke-WebRequest -Uri 'https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks' -Method GET -Headers $headersimport Foundation
let url = URL(string: "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.timeoutInterval = 10
request.allHTTPHeaderFields = ["Authorization": "Bearer <token>"]
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))using RestSharp;
var options = new RestClientOptions("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
var response = await client.GetAsync(request);
Console.WriteLine("{0}", response.Content);
using RestSharp;
var options = new RestClientOptions("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
var response = await client.GetAsync(request);
Console.WriteLine("{0}", response.Content);
CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Authorization: Bearer <token>");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Authorization: Bearer <token>");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);val client = OkHttpClient()
val request = Request.Builder()
.url("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks")
.get()
.addHeader("Authorization", "Bearer <token>")
.build()
val response = client.newCall(request).execute(){
"dimension": "platform",
"buckets": [
{
"key": "<string>",
"humanClicks": 123
}
]
}{
"issues": [
{
"_tag": "Pointer",
"path": [
"<string>"
],
"message": "<string>"
}
],
"message": "<string>",
"_tag": "HttpApiDecodeError"
}{
"message": "<string>",
"_tag": "Unauthorized"
}{
"message": "<string>",
"_tag": "PaymentRequired"
}{
"message": "<string>",
"_tag": "Forbidden"
}{
"message": "<string>",
"_tag": "NotFound"
}{
"message": "<string>",
"_tag": "Conflict",
"code": "<string>",
"currentRevision": 123
}{
"message": "<string>",
"code": "<string>",
"_tag": "UnprocessableEntity"
}{
"message": "<string>",
"_tag": "TooManyRequests",
"code": "<string>",
"retryAfterSeconds": 123
}{
"message": "<string>",
"_tag": "InternalError"
}Shortlinks
Clicks by dimension
Break down one shortlink’s recorded clicks by a grouping dimension (such as referrer, country, or device) within an optional time window. Free: reads stored click events only.
GET
/
v1
/
teams
/
{teamId}
/
shortlinks
/
{id}
/
clicks
TypeScript client
import { OctosparkClient } from '@octospark/sdk'
const client = new OctosparkClient({
token: process.env.OCTOSPARK_TOKEN
})
const response = await client.shortlinks.getClicksByDimension({
teamId: process.env.OCTOSPARK_TEAM_ID ?? "teamId",
id: process.env.OCTOSPARK_ID ?? "id",
query: {
"groupBy": process.env.OCTOSPARK_GROUP_BY ?? "groupBy",
},
})import os
from octospark_sdk import OctosparkClient
client = OctosparkClient(token=os.environ["OCTOSPARK_TOKEN"])
response = client.shortlinks.get_clicks_by_dimension(
teamId=os.environ.get("OCTOSPARK_TEAM_ID", "teamId"),
id=os.environ.get("OCTOSPARK_ID", "id"),
query={
"groupBy": os.environ.get("OCTOSPARK_GROUP_BY", "groupBy"),
}
)octospark shortlinks get-clicks-by-dimension \
--request '{"path":{"teamId":"teamId","id":"id"},"query":{"groupBy":"groupBy","from":"from","to":"to"}}'use reqwest::Client;
use std::env;
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let client = Client::new();
let base_url = env::var("OCTOSPARK_API_URL").unwrap_or_else(|_| "https://api.octospark.ai".to_string());
let team_id = env::var("OCTOSPARK_TEAM_ID").unwrap_or_else(|_| "teamId".to_string());
let id = env::var("OCTOSPARK_ID").unwrap_or_else(|_| "id".to_string());
let group_by = env::var("OCTOSPARK_GROUP_BY").unwrap_or_else(|_| "groupBy".to_string());
let url = format!("{}/v1/teams/{}/shortlinks/{}/clicks", base_url.trim_end_matches('/'), team_id, id);
let token = env::var("OCTOSPARK_TOKEN").expect("OCTOSPARK_TOKEN");
let mut request = client.get(url).bearer_auth(token);
let query = [("groupBy", group_by.as_str())];
request = request.query(&query);
let response = request.send().await?;
println!("{}", response.text().await?);
Ok(())
}import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
Future<void> main() async {
final baseUrl = Platform.environment['OCTOSPARK_API_URL'] ?? 'https://api.octospark.ai';
final token = Platform.environment['OCTOSPARK_TOKEN'];
final teamId = Platform.environment['OCTOSPARK_TEAM_ID'] ?? 'teamId';
final id = Platform.environment['OCTOSPARK_ID'] ?? 'id';
final groupBy = Platform.environment['OCTOSPARK_GROUP_BY'] ?? 'groupBy';
final url = '${baseUrl.replaceFirst(RegExp(r'/$'), '')}/v1/teams/$teamId/shortlinks/$id/clicks';
final uri = Uri.parse(url).replace(queryParameters: {
'groupBy': groupBy,
});
final headers = {
'Authorization': 'Bearer $token',
};
final response = await http.get(
uri,
headers: headers,
);
print(response.body);
}curl --request GET \
--url https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks \
--header 'Authorization: Bearer <token>'<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body$headers=@{}
$headers.Add("Authorization", "Bearer <token>")
$response = Invoke-WebRequest -Uri 'https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks' -Method GET -Headers $headersimport Foundation
let url = URL(string: "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.timeoutInterval = 10
request.allHTTPHeaderFields = ["Authorization": "Bearer <token>"]
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))using RestSharp;
var options = new RestClientOptions("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
var response = await client.GetAsync(request);
Console.WriteLine("{0}", response.Content);
using RestSharp;
var options = new RestClientOptions("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
var response = await client.GetAsync(request);
Console.WriteLine("{0}", response.Content);
CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Authorization: Bearer <token>");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Authorization: Bearer <token>");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);val client = OkHttpClient()
val request = Request.Builder()
.url("https://api-staging.octospark.ai/v1/teams/{teamId}/shortlinks/{id}/clicks")
.get()
.addHeader("Authorization", "Bearer <token>")
.build()
val response = client.newCall(request).execute(){
"dimension": "platform",
"buckets": [
{
"key": "<string>",
"humanClicks": 123
}
]
}{
"issues": [
{
"_tag": "Pointer",
"path": [
"<string>"
],
"message": "<string>"
}
],
"message": "<string>",
"_tag": "HttpApiDecodeError"
}{
"message": "<string>",
"_tag": "Unauthorized"
}{
"message": "<string>",
"_tag": "PaymentRequired"
}{
"message": "<string>",
"_tag": "Forbidden"
}{
"message": "<string>",
"_tag": "NotFound"
}{
"message": "<string>",
"_tag": "Conflict",
"code": "<string>",
"currentRevision": 123
}{
"message": "<string>",
"code": "<string>",
"_tag": "UnprocessableEntity"
}{
"message": "<string>",
"_tag": "TooManyRequests",
"code": "<string>",
"retryAfterSeconds": 123
}{
"message": "<string>",
"_tag": "InternalError"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Team (workspace) id (UUID). Discover ids via the list teams endpoint or the agent context.
Shortlink id (UUID), as returned by the list shortlinks endpoint.
Query Parameters
Dimension to bucket the shortlink's clicks by, e.g. referrer, country, or device.
Available options:
platform, placement, display_mode, content_type, target_domain, referrer, device, country Start of the click window, ISO 8601 timestamp (inclusive); omit for all time.
Example:
"2026-06-01T00:00:00Z"
End of the click window, ISO 8601 timestamp (inclusive); omit for all time.
Example:
"2026-06-30T23:59:59Z"