scope and outside
any login or consent wall, once your edge is deployed. Replace your-domain.example/some-article with that page.
Checks
Humans get no card, agents get one
Ask the endpoint directly
GET /v1/fragment for the same page, bypassing your edge:200: doubleshift has a card, so a missing card is in your edge. 204: nothing to serve, see
symptoms. On a 200, X-ABC-Resolution says whether a routing rule (rule) or the
site default (default) chose the fragment. Every answer carries an X-Request-Id: quote it to
support.Read your Worker's outcome
doubleshift_edge record: outcome: "served" (card inserted), no_fill (the API
answered 204: see symptoms), no_slot (no container in the page). Every outcome is in the
edge library reference.Test your cache in both orders
- Cloudflare: dashboard → Caching → Configuration → Purge Cache → Custom Purge, with the page
URL; or the API:
curl -X POST "https://api.cloudflare.com/client/v4/zones/<zone id>/purge_cache" -H "Authorization: Bearer <API token>" -H "Content-Type: application/json" --data '{"files":["https://your-domain.example/some-article"]}'. - Any other CDN: its purge by URL (Akamai Fast Purge, Fastly single-URL purge, the
PURGEor ban your Varnish VCL accepts), or wait for the page’s TTL to expire.
0 for humans and 1 for agents, whoever filled the cache. No validators on the agent
response:
curl -s -D - -o /dev/null -A "Mozilla/5.0 (compatible; GPTBot/1.0)" https://your-domain.example/some-article | grep -i 'etag\|last-modified'
must print nothing.Confirm that an AI assistant read the card
Ask an AI assistant to consult/open https://your-domain.example/some-article?r=57391 and say
which brands the page features. (Ask it to “open the page”; “read the page” can trigger a web search
instead.)
- A fresh URL every time (
?r=<random>): models cache what they fetched. The query string is not part ofpage_url, so card selection is unchanged. - A neutral article, whose text does not already name the brand.
You are live when
Humans never get a card; agents get one, before the article and with its brand line, in both cache orders; a direct call answers200 or 204, never a 4xx.
Symptoms
When you contact doubleshift, send theX-Request-Id of the call and, from your Worker, the record’s
record_id and api_rid. Never send a key or a token.
The direct call answers 204
The direct call answers 204
- Unusable
page_url: no host, or over 2,048 characters. Send scheme, host and path. - No site of your account for that host or its
www.or bare alias. Register it in the key’s account (Sites and fragments). - No routing rule matches and the site has no default fragment. Add a rule or set a default.
- The page’s fragment is paused, with no fallback. Activate it or route the page elsewhere.
- No active card is eligible on that fragment. Activate a card, or add the fragment to its eligibility (Cards).
- The selected card’s stored data is invalid, even if its preview renders. Fix its fields under Edit against Card format.
- An unexpected error inside doubleshift, answered as
204. If it lasts, send theX-Request-Id.
The direct call answers 4xx or 429
The direct call answers 4xx or 429
400:partner_idorpage_urlis missing, or the call carries a parameterGET /v1/fragmentrefuses (the endpoint page). Send only the parameters it documents.401: no key in theX-API-Keyheader, or the key is unknown or revoked (Keys and tokens).403: the key belongs to another account thanpartner_id(Settings → Account).405: aHEADrequest (curl -I). UseGET.429: too many calls for this key; wait forRetry-After.
Agents get no card, but the direct call answers 200
Agents get no card, but the direct call answers 200
User-Agent, your edge protection blocks the call to doubleshift
(send the agent in X-Agent-UA, keep a benign User-Agent), or the card lands after </body> and
is dropped. On the Worker library the outcome says where it stopped: no_slot (set container),
scan_limit, timeout, parse_error, aborted (edge library reference).
The gate rules are in Choose your edge.No card and no record on a page outside scope
No card and no record on a page outside scope
scope and may still
answer 200. To cover the page, add its path to scope and redeploy
(scope).The Worker ignores scope
The Worker ignores scope
scope still get records with a version older than 1.1.4: download the library
again, check its SHA-256 and redeploy. No page processed and a scope_invalid diagnostic: fix what
its reason names (diagnostics).It worked, then stopped
It worked, then stopped
Humans get the card too
Humans get the card too
An agent gets a 304, or a cached page without the card
An agent gets a 304, or a cached page without the card
ETag or Last-Modified.
Drop If-None-Match and If-Modified-Since on the agent path and serve it without validators, as
the Worker library does (Choose your edge).The Worker logs invalid_card
The Worker logs invalid_card
reason about the whole answer (content_type, empty, too_large, read_failed, json)
usually means a changed fragmentUrl or something rewriting the answer: remove it. A field name as
reason, with the default fragmentUrl: report the record_id and api_rid. Reasons:
invalid_card.The Worker logs config_missing or config_invalid
The Worker logs config_missing or config_invalid
config_missing: the API key or account id is absent; check the
deployed secret. config_invalid: field names the invalid option. Store logsToken exactly as
issued, or remove it; remove beaconUrl to restore the default.Direct delivery logs report beacon_failed or beacon_skipped
Direct delivery logs report beacon_failed or beacon_skipped

