> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shftd2.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Publishers integrate one API: GET https://api.shftd2.com/v1/fragment?partner_id=<account id>&page_url=<page URL>, called from their edge for AI-agent requests only, with the API key in the X-API-Key header, never in the query string.
> A 200 carries the card. A 204 means no card: serve the page unchanged.
> The management API (https://api.shftd2.com/v1/me, /v1/sites, /v1/cards, /v1/keys) is optional tooling for scripting setup. It takes its own management token (Authorization: Bearer ds_mgmt_…). Its limits (120 requests and 60 writes per minute per token) do not apply to the delivery API.
> Delivery logs reach doubleshift only through direct delivery logs (POST https://logs.shftd2.com/v1/beacon with a logs token; the edge library with a logsToken is its provided client, and a custom sender may use the same endpoint) or a Cloudflare Logpush job configured with doubleshift. Otherwise doubleshift sees only its own API activity.

# Quickstart

> From an account to a card on a live page with a Cloudflare Worker: register a site, route a section to a fragment, create a key, deploy the doubleshift edge library limited to that section, then check that humans get no card and agents get one.

Five steps, from an account to a card on one section of a live site, on a Cloudflare Worker. Steps 1
to 3 happen in the [console](https://app.shftd2.com) and are the same on every edge; on Vercel or ESI,
do them, then follow your page in [Integrate](https://docs.shftd2.com/integrate.md).

You need:

* a doubleshift account where you are an **owner**: only an owner creates API keys;
* a site served through Cloudflare, and a Wrangler project for the Worker (`wrangler.jsonc` or
  `wrangler.toml`) that you can deploy on that zone;
* one public HTML article in the section you start with (`/articles/` below), not behind a login or a
  consent wall.

**1. Register your site**

In the console, open [Sites & fragments](https://app.shftd2.com/sites) and add your **bare
domain**, host only: `https://your-domain.example/news` becomes `your-domain.example`. See
[Sites and fragments](https://docs.shftd2.com/sites.md).

**2. Route a section to a fragment**

Open the site and create a fragment: a name and a language. It starts **active**. Under **Routing
rules**, enter your section's path, `/articles/`, choose **prefix**, select that fragment, then
**Add rule**. Pages under `/articles/` now resolve to it; no default fragment is needed. See
[How delivery works](https://docs.shftd2.com/how-it-works.md#resolution).

For step 5 to show a card, at least one active card must be eligible on that fragment. A card with
no fragment selected in its eligibility is eligible everywhere. See [Cards](https://docs.shftd2.com/cards.md).

**3. Create a delivery key**

Open **Settings → API keys** and create a key. It is shown once: copy it now. Note your account id
(`acc_…`), shown in the console: it is the `partnerId` below. The key stays server-side, in a
Worker secret; see [API keys](https://docs.shftd2.com/api-keys.md).

**4. Deploy the Worker with the edge library**

Get the library, version 1.1.4 or later, and check its SHA-256:

```bash theme={"theme":{"light":"css-variables","dark":"css-variables"}}
curl -sO https://api.shftd2.com/edge/doubleshift-edge.v1.js
shasum -a 256 doubleshift-edge.v1.js
# v1.1.4 — expected: d4db890cbf27a2da1977d3ba76e0585ab3bf7cc78111eaddc71019527114e9d1
```

Save `doubleshift-edge.v1.js` next to your Worker entry file and commit it, replacing any older
copy: before 1.1.4, `scope` is ignored and every page is processed. Then store the key as a Worker
secret, out of the code:

```bash theme={"theme":{"light":"css-variables","dark":"css-variables"}}
npx wrangler secret put DOUBLESHIFT_API_KEY
```

In the console, open the site, then the fragment's **Integration** page. The routing rules that
target this fragment are selected, and the Worker code there carries their paths in `scope`. Use it
as a new Worker, or add its two lines to a Worker you already run:

```js title="worker.js — standalone" theme={"theme":{"light":"css-variables","dark":"css-variables"}}
import { enrichWithDoubleshift, prepareOriginRequest } from "./doubleshift-edge.v1.js";

export default {
  async fetch(request, env, ctx) {
    const response = await fetch(prepareOriginRequest(request)); // your origin, as today
    return enrichWithDoubleshift(request, response, {
      apiKey: env.DOUBLESHIFT_API_KEY,
      partnerId: "<your account id>",
      scope: { include: ["/articles/*"] },
    }, ctx);
  },
};
```

```js title="Inside an existing Worker" theme={"theme":{"light":"css-variables","dark":"css-variables"}}
import { enrichWithDoubleshift, prepareOriginRequest } from "./doubleshift-edge.v1.js";
// ... where you fetch and return the page:
const response = await fetch(prepareOriginRequest(request)); // instead of fetch(request)
return enrichWithDoubleshift(request, response, { apiKey: env.DOUBLESHIFT_API_KEY, partnerId: "<your account id>", scope: { include: ["/articles/*"] } }, ctx);
```

Replace `<your account id>`, and `/articles/*` with the paths the console shows; outside them, the
Worker leaves the page alone. To cover the whole site, choose **Every page of
your-domain.example** in the console: the Worker then has no `scope`. Patterns and limits:
[scope](https://docs.shftd2.com/api/edge-library.md#scope).

`prepareOriginRequest` drops `If-None-Match` and `If-Modified-Since` from an AI agent's `GET`;
every other request is returned untouched. Pass `response` as `fetch()` returned it: do not read
its body, and do not compress it yourself. Nothing changes in your templates: the card goes right
before the first `<article>`, and a page without one is served intact.

Give the Worker a route on the hostname you will test, or it never sees your pages: in its Wrangler
configuration, or in the Cloudflare dashboard under the Worker's **Settings → Domains & Routes**.
Keep the route broad and let `scope` pick the paths
([routes and scope](https://docs.shftd2.com/integrate/cloudflare-worker.md#routes-and-scope)).

```jsonc title="wrangler.jsonc" theme={"theme":{"light":"css-variables","dark":"css-variables"}}
"routes": [{ "pattern": "your-domain.example/*", "zone_name": "your-domain.example" }]
```

Then deploy:

```bash theme={"theme":{"light":"css-variables","dark":"css-variables"}}
npx wrangler deploy
```

**5. Check humans, agents and scope**

Request your article as a human, then as an AI agent, then a page outside `scope` as an AI agent:

```bash title="Human" theme={"theme":{"light":"css-variables","dark":"css-variables"}}
# Expect 0: no card for humans.
curl -s https://your-domain.example/articles/some-article | grep -c 'abc-card'
```

```bash title="AI agent" theme={"theme":{"light":"css-variables","dark":"css-variables"}}
# Expect 1: one card for agents.
curl -s -A "Mozilla/5.0 (compatible; GPTBot/1.0)" \
  https://your-domain.example/articles/some-article | grep -c 'abc-card'
```

```bash title="Outside scope" theme={"theme":{"light":"css-variables","dark":"css-variables"}}
# Expect 0: the Worker leaves this page alone.
curl -s -A "Mozilla/5.0 (compatible; GPTBot/1.0)" \
  https://your-domain.example/about | grep -c 'abc-card'
```

Human `0`, agent `1`, outside `0` is a first presence check: the card reaches agents only, on your
section only. It does not check where the card sits, the brand line or your cache. Run
[Verify and troubleshoot](https://docs.shftd2.com/verify.md) before you call the page live; any other result has a known
cause and fix there.

Next: [Cloudflare Worker](https://docs.shftd2.com/integrate/cloudflare-worker.md) covers routes and `scope`, several sites, delivery logs, updating the library and watching its records.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.