Authentication

Every request to the embed API is authenticated with a bearer token. Wallet Sleuth issues two tiers of keys per tracking page:

TierPrefixWhere it can runOrigin check
Publicws_pub_Browsers, iframes, any client-side code.Required — request Origin must be on the key's allowlist.
Secretws_sec_Server-side only. Never ship to a browser.Not enforced — any origin accepted. Secret keys also satisfy all public endpoints for owner testing.

Keys are scoped to a single tracking page. A key issued for page abc123 cannot read or write to page xyz789; the server rejects the request with invalid_key even if the key itself is valid.

Key format

Keys are opaque strings: a tier prefix plus 32 base62 characters. Example (synthetic, not a live key):

ws_pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The server stores only a securely hashed copy of the full key, plus a short display prefix (e.g. ws_pub_XG9y). You cannot recover a key from the dashboard after it's shown once at creation time. If you lose a key, revoke it and issue a new one.

Sending the key

Every request includes a Bearer token:

GET /api/embed/tracking/abc123 HTTP/1.1
Host: walletsleuth.app
Authorization: Bearer ws_pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Origin: https://example.com
  • Authorization is required on every request to a public endpoint.
  • Origin is required when using a public key. The server falls back to Referer if Origin is missing, but reliable behavior requires Origin.

Missing or malformed bearer → 401 missing_key. Wrong prefix (not ws_pub_ or ws_sec_) → 401 invalid_key. Key doesn't exist or belongs to a different page → 401 invalid_key. Revoked key → 401 revoked_key.

Public keys and origin allowlisting

When you create a public key, you list the origins that are allowed to use it. An origin is the tuple <scheme>://<host>[:<port>]. The allowlist is case-insensitive and port-aware (default ports :443 and :80 are treated as absent).

Valid:

https://example.com
https://staging.example.com
https://example.com:8443

Invalid (will be rejected by the dashboard or never match a request):

example.com              # no scheme
https://*.example.com    # wildcards are not supported
https://example.com/app  # path is ignored

On each request, the server normalizes the request's Origin header and checks whether it's in the key's allowlist. A miss returns:

  • 403 origin_not_allowed — if an origin was sent but isn't allowlisted.
  • 401 missing_origin — if no Origin or Referer header was sent at all.

Null-origin requests

Some contexts (e.g. file:// pages, sandboxed iframes, direct cURL from a terminal) send no Origin header. The dashboard has an Allow null origin flag on the key, off by default. Enable it only when you intentionally want the key to work from those contexts; it weakens the allowlist's guarantees.

The same-origin bypass

The embed iframe's own calls to the API are treated as trusted without being on your allowlist; you don't need to configure anything.

Secret keys

Secret keys exist for server-side use cases where you need to proxy an API call through your own backend (for example, to avoid shipping any key to browsers, or to aggregate multiple pages behind your own API). A secret key:

  • Has no origin allowlist. Any caller with the key is trusted.
  • Satisfies the requiredTier: 'public' check on every public endpoint, so you can use it for the same reads as a public key.
  • Is never embedded in the iframe. The iframe route at /embed/tracking/{id}?key=… rejects secret keys outright.

Treat secret keys like database credentials. Store them in your secrets manager, load them as environment variables, and rotate them on compromise.

Revocation

In the dashboard, hit the trash icon next to a key to revoke it. Revocation is immediate and server-side: the next request using that key returns 401 revoked_key. There's no grace period, so revocations break running embeds instantly — issue a new key and swap it in first if you're doing a scheduled rotation.

What to check if auth is failing

  1. Request looks right? Authorization: Bearer <full key> — no quotes, no whitespace.
  2. Correct tracking page? The path segment /api/embed/tracking/{id} must match the page the key was issued for.
  3. Origin header present? Browser fetches usually send it automatically; cURL needs -H 'Origin: https://example.com'.
  4. Origin allowlisted? Exact scheme + host + port match. Add localhost or preview URLs explicitly.
  5. Key not revoked? Check the key's status in the dashboard.

When in doubt, read the error field on the 4xx response and cross-reference Errors and status codes. See Cooldowns and rate limits for 429 handling.