GET /api/embed/tracking/{id}

Returns the public payload for a tracking page. This is the same data the iframe widget renders; use it to build a custom UI.

Request

GET /api/embed/tracking/{trackingPageId} HTTP/1.1
Host: walletsleuth.app
Authorization: Bearer ws_pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Origin: https://example.com

Path parameters

NameTypeDescription
trackingPageIdstringThe tracking page ID. Visible in the Wallet Sleuth dashboard URL.

Headers

HeaderRequiredNotes
AuthorizationyesBearer <api_key>. Public or secret tier accepted.
Originyes for public keysMust be on the key's allowlist (unless allowNullOrigin is set).

Query parameters

None.

Body

None — this is a GET.

Success response

200 OK, JSON body:

{
  "tokenName": "Solana",
  "tokenSymbol": "SOL",
  "tokenMint": "So11111111111111111111111111111111111111112",
  "publicTitle": "Team + early holders",
  "publicComments": "Updated every few minutes.",
  "wallets": [
    {
      "id": "wallet-doc-id",
      "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
      "publicAlias": "Core dev",
      "tokenBalance": 125000,
      "tags": [
        { "id": "tag-1", "name": "Team member", "color": "purple" }
      ]
    }
  ],
  "tags": [
    { "id": "tag-1", "name": "Team member", "color": "purple" },
    { "id": "tag-2", "name": "Bad actor", "color": "red" }
  ]
}

Response fields

FieldTypeNotes
tokenNamestringFrom the tracking page's token metadata.
tokenSymbolstringTicker. Displayed with $ prefix in the widget.
tokenMintstringBase58 mint address of the tracked token.
publicTitlestring | nullSecondary header set by the owner. Null if unset.
publicCommentsstring | nullShort blurb set by the owner. Null if unset.
walletsarrayEvery tracked wallet not marked hideFromPublic.
wallets[].idstringWallet document ID — stable across calls.
wallets[].addressstringBase58 Solana address.
wallets[].publicAliasstring | nullOwner-configured display name. Null if unset.
wallets[].tokenBalancenumberRaw token balance (not USD). Zero if never observed.
wallets[].tagsarrayTag objects applied to the wallet. Subset of top-level tags.
tagsarrayAll tags defined on the tracking page. Wallet tag arrays are subsets of this.
tags[].idstringTag document ID.
tags[].namestringOwner-configured display name.
tags[].colorstringColor token name (e.g. "purple", "red").

The list is already filtered: wallets with hideFromPublic: true on their public settings doc are never returned.

Error responses

All errors follow the shape { "error": "<code>" }. HTTP status and code combinations:

StatuserrorMeaning
401missing_keyNo Authorization: Bearer … header.
401invalid_keyKey prefix is wrong, key doesn't exist, or key belongs to a different page.
401revoked_keyKey has been revoked.
401missing_originPublic-key request had no Origin or Referer header.
403origin_not_allowedOrigin isn't on the key's allowlist.
403embed_disabledTracking page is private or has embedding disabled.
404not_foundTracking page doesn't exist, or its data can't be built.
429rate_limit_keyPer-key rate limit exceeded. Retry-After included.
429rate_limit_ipPer-IP rate limit exceeded. Retry-After included.

For the complete table across every endpoint, see Errors and status codes.

Preflight (OPTIONS)

Browsers will issue a preflight OPTIONS request before cross-origin GETs with custom headers. The server responds 204 No Content with:

Access-Control-Allow-Origin: <your origin>
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 600
Vary: Origin

Preflight runs a lightweight version of the origin check: if any public, non-revoked key for the tracking page has your origin allowlisted, preflight succeeds. The actual GET then does the full check against the specific key you presented.

Caching

The server does not set Cache-Control. Don't cache this response in shared caches — the wallet list changes as owners add and remove wallets, and tokenBalance changes as transactions land. The global per-key and per-IP rate limits are generous enough for polling at roughly 1 req/s if you need near-live updates.

Example (cURL)

curl -s https://walletsleuth.app/api/embed/tracking/abc123 \
  -H 'Authorization: Bearer ws_pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
  -H 'Origin: https://example.com'

Example (fetch)

const res = await fetch(
  `https://walletsleuth.app/api/embed/tracking/${pageId}`,
  {
    headers: {
      Authorization: `Bearer ${publicKey}`,
    },
    credentials: 'include',
  },
);
if (!res.ok) {
  const { error } = await res.json();
  throw new Error(error);
}
const payload = await res.json();

Browsers set Origin automatically. credentials: 'include' is needed only if you also want the embed session cookie to be sent (required for GET /session/submissions).

Related