> ## 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.

# Reference

> The HTTP contract of the fragment endpoint, the canonical AI-agent markers, and the abc.txt format.

export const Pill = ({variant = "alpha", children}) => <span className={`ds-pill ${variant}`}>{children}</span>;

The HTTP contract of the fragment endpoint, the canonical AI-agent markers, and the `abc.txt` format.

## Fragment endpoint

`GET https://api.shftd2.com/fragment` is served directly by doubleshift. It authenticates with your API
key, selects a card, and returns it. The response depends only on the page and context, never on the
visitor's `User-Agent` (the UA is read only for reporting), so every `200`/`204` is cacheable by URL with
**no `Vary: User-Agent`**.

The previous host, `app.shftd2.com/fragment`, keeps serving identically as a legacy alias (it is not
redirected). Use `api.shftd2.com` for new integrations.

### Parameters

| Param         | Type   | Required | Notes                                                                                                                                                                       |
| ------------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `partner_id`  | string | yes      | Your account id. Must match the account that owns the API key, or 403.                                                                                                      |
| `fragment_id` | string | yes      | The fragment id. Must belong to the API key's account, or 403.                                                                                                              |
| `lang`        | string | yes      | Fragment language (fr, en, de, es, it).                                                                                                                                     |
| `api_key`     | string | yes\*    | API key from Settings. \*Send as api\_key query param OR X-API-Key header.                                                                                                  |
| `page_url`    | string | no\*     | \*The endpoint answers without it, but brand-aware selection and page-level reporting both need it. Send scheme + host + path, with the query string and fragment stripped. |
| `ctx.<key>`   | string | no       | Targeting values (your fragment key-values). Each non-empty value influences which card is picked; a value that matches nothing does not cause a no-fill.                   |
| `format`      | string | no       | html (default) · json · both. Controls the response body shape.                                                                                                             |

The endpoint also accepts the legacy `placement_id` as a deprecated alias for `fragment_id`.

### Response codes

| Code                                | Meaning                                                                                                                                                                                                                                                     |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <Pill variant="code-200">200</Pill> | A card is eligible. Body is the card: text/html (or JSON with format=json/both). Cacheable by URL.                                                                                                                                                          |
| <Pill variant="code-204">204</Pill> | No-fill: no card was returned, because nothing was eligible, the fragment is paused, or a serving error occurred. Empty body. Cacheable. doubleshift records the reason per request; your edge always fails open, so the page renders unchanged either way. |
| <Pill variant="code-err">400</Pill> | Bad request: partner\_id, fragment\_id or lang missing.                                                                                                                                                                                                     |
| <Pill variant="code-err">401</Pill> | Missing or invalid API key.                                                                                                                                                                                                                                 |
| <Pill variant="code-err">403</Pill> | API key valid but not authorized for this partner\_id / fragment\_id.                                                                                                                                                                                       |

Success and no-fill responses carry `Cache-Control: public, s-maxage=120, stale-while-revalidate=240`;
error responses are `Cache-Control: no-store`. A successful `html` response is `Content-Type: text/html; charset=UTF-8`.

## Known AI agents (v0.1)

Your edge gates card requests on these markers, matched **word-boundary, case-insensitive** against the
request `User-Agent`. Only a match triggers a card request; everyone else gets the page unchanged.
Robots.txt-only control tokens (e.g. `Google-Extended`) are deliberately excluded, since they never appear in
a request's `User-Agent`.

| Marker                  | Family      | Purpose  |
| ----------------------- | ----------- | -------- |
| `GPTBot`                | openai      | training |
| `ChatGPT-User`          | openai      | query    |
| `OAI-SearchBot`         | openai      | search   |
| `ClaudeBot`             | anthropic   | training |
| `Claude-User`           | anthropic   | query    |
| `Claude-SearchBot`      | anthropic   | search   |
| `Google-CloudVertexBot` | google      | search   |
| `PerplexityBot`         | perplexity  | search   |
| `Perplexity-User`       | perplexity  | query    |
| `CCBot`                 | commoncrawl | training |
| `Meta-ExternalAgent`    | meta        | training |
| `meta-externalfetcher`  | meta        | query    |
| `Bytespider`            | bytedance   | training |
| `YouBot`                | you         | search   |
| `Diffbot`               | diffbot     | training |
| `MistralAI-User`        | mistral     | query    |
| `Amazonbot`             | amazon      | unknown  |

**Purpose** axis: `query` (real-time fetch for a user asking now), `search` (building/refreshing an AI
search index), `training` (bulk crawl for a training corpus), `unknown` (mixed or undocumented). The
canonical, machine-readable list is `schema/agents.json` on [brandedcontent.dev](https://brandedcontent.dev)
Keep your edge regex in sync with it.

## abc.txt format

```text title="abc.txt" theme={"theme":"css-variables"}
# abc.txt - Agentic Branded Content
# Spec: https://brandedcontent.dev
shftd2.com, <your account id>, DIRECT
```

* One line per provider: `provider_domain, account_id, relationship`.
* `relationship` is `DIRECT` (you control the account) or `RESELLER` (a partner resells on your behalf).
* `text/plain`, ASCII; `#` starts a comment. Unknown fields are ignored, so the format can grow.
* Served at `https://<your-domain>/abc.txt`. Optional: cards are delivered without it.

<Note>
  **Where these definitions come from**

  The live `GET /fragment` route defines the endpoint contract. [brandedcontent.dev](https://brandedcontent.dev)
  defines the agent registry and the `abc.txt` format.
</Note>
