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

# Delivery logs

> Where your Worker's delivery records go: sent directly by the edge library, exported by a Cloudflare Logpush job, or kept in your own logs. What each option gives you, and how to set it up.

Your Worker writes delivery records locally; doubleshift receives them only through direct delivery
logs or a configured Cloudflare Logpush job, and otherwise sees only its own API activity. Sending
them lets doubleshift compare its API answers with your page outcomes; it does not prove that an agent
read the card.

## Where your delivery records go

| Option | What you set up | What reaches doubleshift |
| - | - | - |
| **Direct sending** | Edge library 1.1.3 or later, a logs token for direct sending in `logsToken`, and `ctx`. | Each record, sent in the background, pages without a card included. No queue: after a final failure the library writes `beacon_failed`. |
| **Logpush** | A logs token for Logpush and a Logpush job on your Cloudflare account (Workers Paid). A valid option for a site on Cloudflare. | Your Worker's console output, in batches on Cloudflare's schedule. |
| **Nothing sent** | The default: no `logsToken`, no Logpush job; the Vercel and ESI snippets provided send no records. A custom sender can use the [direct delivery logs API](https://docs.shftd2.com/api/beacon.md). | Nothing from your Worker: doubleshift cannot tell whether the card reached the page, nor see pages that made no call (`no_slot`…). |

[Reporting](https://docs.shftd2.com/reporting.md) is the same in all three cases: it counts served calls. Use one transport per
Worker, never both at once. The two logs tokens are not interchangeable: each endpoint
refuses the other's token with `403` `wrong_transport`.

With the [CloudFront kit](https://docs.shftd2.com/integrate/cloudfront.md), direct sending is the template parameter `DsLogsToken`; the
records also stay in the composer's CloudWatch Logs.

## Turn on direct sending

**1. Ask doubleshift for a logs token for direct sending**

Not your API key nor a Logpush token ([Keys and tokens](https://docs.shftd2.com/api-keys.md)).

**2. Store it as a Worker secret**

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

**3. Add the option and redeploy**

```js theme={"theme":{"light":"css-variables","dark":"css-variables"}}
logsToken: env.DOUBLESHIFT_LOGS_TOKEN,
```

Add it next to `apiKey` and `partnerId`, keep passing `ctx`, then `npx wrangler deploy`. A missing
or empty secret leaves sending off, silently. Keep `quietInfo` at `false` while you
[check the setup](https://docs.shftd2.com/verify.md).

The request the library sends, its codes and its retries: [Direct delivery logs API](https://docs.shftd2.com/api/beacon.md).

## Logpush

**1. Ask doubleshift for a logs token for Logpush**

Not the direct-sending token.

**2. Enable Logpush on the Worker**

Add `"logpush": true` to the `wrangler.jsonc` of the Worker that runs the library
(`logpush = true` in `wrangler.toml`), then redeploy with `npx wrangler deploy`.

**3. Create the Logpush job**

With a Cloudflare API token that has **Logs Edit**
([Logpush access](https://developers.cloudflare.com/workers/observability/logs/logpush/#verify-your-logpush-access)),
`POST https://api.cloudflare.com/client/v4/accounts/<account id>/logpush/jobs` with this body,
and leave `logsToken` unset.

```json title="Logpush job" theme={"theme":{"light":"css-variables","dark":"css-variables"}}
{
  "name": "doubleshift-delivery-logs",
  "enabled": true,
  "dataset": "workers_trace_events",
  "filter": "{\"where\":{\"key\":\"ScriptName\",\"operator\":\"eq\",\"value\":\"<your Worker name>\"}}",
  "output_options": {
    "field_names": ["EventTimestampMs", "EventType", "Logs", "Outcome", "ScriptName", "ScriptVersion"]
  },
  "max_upload_bytes": 5000000,
  "max_upload_interval_seconds": 30,
  "destination_conf": "https://logs.shftd2.com/v1/logpush?header_Authorization=Bearer%20<your logs token for Logpush>"
}
```

Check `enabled` in the response. Do not add the `Event` field: it carries request metadata.

**4. Check the first batch**

Request an article as an AI agent, then read the job's `last_complete` and `last_error`. An upload
means Cloudflare delivered a batch; ask doubleshift to confirm processing.

* **The whole console output is exported**, `page_url` included: the filter selects a Worker, not an
  event. Silent invocations still count toward Logpush usage. `Logs` and `Exceptions` share 16,384
  characters per invocation, then messages are truncated and dropped.
* **Keep the records in the console**: no custom `log` function that replaces it, and `quietInfo` at
  `false`.


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