List taps
method
GET
host
strait.
version
/v1
resource
/
GET /v1/taps
Auth: secret key as Authorization: Bearer. Server-side only.
Request
Every tap (one row per person tapping a link), oldest first, as cursor pages: { taps, nextCursor }; pass nextCursor back as cursor until it is null. Each tap carries where it was sent, its channel and campaign, and its first app open and install. The same rows as GET /v1/export?part=taps, for syncing into your own tools. Link-preview bots are not taps. Secret key with read or full access; 30 reads a minute per workspace, shared with GET /v1/events.
Parameters
limitinteger query- 1–100, default 50
cursorstring querynextCursorfrom the previous pagefromstring query- Inclusive start: ISO date (UTC), ISO date-time or epoch ms
tostring query- Exclusive end, same formats
linkstring query- Only this active link's taps (its slug)
Response
- 200 A page of taps
- 400 Bad limit, cursor, from / to or link
- 401 Missing or invalid secret key, or a publishable key
- 403 The key is limited to links
- 404 No active link with that slug
- 429 Over 30 reads a minute for this workspace (Retry-After)
curl -X GET https://strait.link/v1/taps \
-H "Authorization: Bearer $SECRET_KEY"const res = await fetch('https://strait.link/v1/taps', {
headers: { Authorization: `Bearer ${process.env.SECRET_KEY}` },
});
const data = await res.json();
console.log(res.status, data);import os
import requests
res = requests.get(
"https://strait.link/v1/taps",
headers={"Authorization": f"Bearer {os.environ['SECRET_KEY']}"},
)
print(res.status_code, res.json())<?php
// Plain PHP with ext-curl, no packages. In Laravel, Http::withToken($secretKey)->get($url) sends the same request.
$ch = curl_init('https://strait.link/v1/taps');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('SECRET_KEY'),
],
]);
$response = curl_exec($ch);
if ($response === false) {
throw new RuntimeException(curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
echo $status, PHP_EOL;
print_r(json_decode($response, true));import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
// Java 17+, java.net.http only (no dependencies).
public class Main {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://strait.link/v1/taps"))
.header("Authorization", "Bearer " + System.getenv("SECRET_KEY"))
.GET()
.build();
HttpResponse<String> res = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(res.statusCode() + " " + res.body());
}
}package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest(http.MethodGet, "https://strait.link/v1/taps", nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("SECRET_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(res.StatusCode, string(data))
}The response, printed
{
"taps": [
{
"clickId": "9a1c7e52-4b3d-4f8e-a1c2-7d6e5f4a3b21",
"clickedAt": "2026-10-01T10:00:00.000Z",
"linkId": "lnk_5f0c2a8e-3b1d-4f6a-9c7e-2d8b1a0e4f63",
"slug": "summer",
"source": "web",
"platform": "android",
"deviceClass": "phone",
"osMajor": 15,
"inAppBrowser": null,
"channel": "whatsapp",
"sentTo": "app_or_store",
"campaign": "diwali",
"variant": null,
"billable": true,
"opens": 1,
"openedAt": "2026-10-01T10:00:04.000Z",
"openKind": "direct",
"openRoute": "app_link",
"appState": "closed",
"isNewUser": false,
"installedAt": null,
"installMatched": null,
"matchMethod": null
}
],
"nextCursor": "WyIyMDI2LTEwLTAxVDEwOjAwOjAwLjAwMDAwMCswMDowMCIsIjlhMWM3ZTUyIl0"
}