Authentication
Every request to the embed API is authenticated with a bearer token. Wallet Sleuth issues two tiers of keys per tracking page:
| Tier | Prefix | Where it can run | Origin check |
|---|---|---|---|
| Public | ws_pub_ | Browsers, iframes, any client-side code. | Required — request Origin must be on the key's allowlist. |
| Secret | ws_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
Authorizationis required on every request to a public endpoint.Originis required when using a public key. The server falls back toRefererifOriginis missing, but reliable behavior requiresOrigin.
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 noOriginorRefererheader 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
- Request looks right?
Authorization: Bearer <full key>— no quotes, no whitespace. - Correct tracking page? The path segment
/api/embed/tracking/{id}must match the page the key was issued for. - Origin header present? Browser fetches usually send it automatically; cURL needs
-H 'Origin: https://example.com'. - Origin allowlisted? Exact scheme + host + port match. Add localhost or preview URLs explicitly.
- 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.