> ## Documentation Index
> Fetch the complete documentation index at: https://payload-storage-bunny.seshuk.im/llms.txt
> Use this file to discover all available pages before exploring further.

# Telemetry

> Anonymous, opt-out usage telemetry: what is collected, what is never sent, and how to turn it off.

The plugin sends a small, anonymous usage report once per day so the maintainer can see which Payload and plugin versions are in use and which features are worth supporting. It is **opt-out** and **disclosed**: a one-time notice prints to your server logs on first run.

No secrets, IPs, keys, zone/library/bucket names, hostnames, countries, file paths, or collection names ever leave your server.

## What is collected

Every report is a single JSON document with these fields:

| Field | Example | Notes |
| - | - | - |
| `product` | `payload-storage-bunny` | Fixed slug for this plugin. |
| `productVersion` | `3.1.0` | Installed plugin version. |
| `payloadVersion` | `3.86.0` | Installed Payload version. |
| `runtime` | `node` | Always Node for this plugin. |
| `runtimeVersion` | `22` | Node major version only. |
| `os` | `linux` | `process.platform`, lowercased. |
| `projectId` | `b3f1a9c2…` | Anonymous hash — see [below](#how-projectid-is-derived). |
| `projectIdSource` | `git` | Which source produced the hash. |
| `features` | `{ "stream": true, … }` | Booleans only — see [below](#feature-flags). |

### Feature flags

`features` is a flat map of booleans derived from your **resolved** options. It records only whether a capability is on, never any value tied to it:

| Flag | Meaning |
| - | - |
| `storage` | Bunny Storage is configured. |
| `storageS3` | A storage zone uses the S3-compatible backend (vs the HTTP API). |
| `storageClientUploads` | Browser-direct uploads are enabled. |
| `storageClientUploadsEdge` | Client uploads go through an Edge Script (vs presigned S3). |
| `stream` | Bunny Stream is configured. |
| `streamTus` | TUS resumable uploads are enabled. |
| `streamTusAutoMode` | TUS auto-mode is on. |
| `streamCleanup` | The incomplete-upload cleanup task is enabled. |
| `streamWebhook` | A Stream status webhook is configured. |
| `thumbnail` | Thumbnails are enabled. |
| `signedUrls` | Signed URLs are enabled. |
| `signedUrlsCountryLock` | Signed URLs set an allowed/blocked country list. |
| `cdnPurge` | CDN cache purging is enabled. |
| `urlTransform` | URL transformation is enabled. |
| `collectionOverrides` | At least one collection uses object options (not just `true`). |
| `collectionZones` | At least one collection defines its own zone/library. |
| `accountApiKey` | An account-level API key is set. |

## How `projectId` is derived

`projectId` is a one-way, irreversible hash:

```
projectId = sha256( payload.secret + rawSource )
```

`payload.secret` is used **only as a salt** and is never transmitted — it is high-entropy and private, so the digest cannot be reversed. This mirrors how Payload derives its own telemetry id.

`rawSource` is the first available of, reported as `projectIdSource`:

1. `git` — the repository's `remote.origin.url`
2. `packageJSON` — your app's `package.json` `name`
3. `serverURL` — `payload.config.serverURL`
4. `cwd` — the process working directory

Only the salted hash is sent — never the git URL, package name, or server URL themselves.

## What is never sent

No IP address, no `payload.secret`, no API keys, no zone / bucket / library / domain names, no file paths, no collection names, no country codes, and no URL-transform internals. `features` carries booleans only.

## Opting out

Telemetry is disabled automatically if **any** of these is true:

* `payload.config.telemetry` is `false` (the host's own Payload opt-out)
* the plugin's `telemetry` is `false`
* the `BUNNY_TELEMETRY_DISABLED` or `DO_NOT_TRACK` environment variable is set to a truthy value
* a `CI` environment is detected
* `NODE_ENV` is `test`

To opt out explicitly:

```ts payload.config.ts theme={null}
bunnyStorage({
  collections: { media: true },
  storage: {/* ... */},
  telemetry: false,
})
```

Or via the environment (respects the cross-tool [Console Do Not Track](https://consoledonottrack.com/) standard):

```bash theme={null}
DO_NOT_TRACK=1
# or, plugin-specific:
BUNNY_TELEMETRY_DISABLED=1
```

## Sending to your own collector

Pass an object with a `url` to point reports at a collector you control:

```ts payload.config.ts theme={null}
telemetry: {
  url: 'https://telemetry.example.com/v1/collect'
}
```

## Transport

Reports are **fire-and-forget**: they never block boot, never throw, and are capped at a 2-second timeout — a telemetry failure can never affect your application. At most one report is sent per project per UTC day (best-effort, via a timestamp in the OS temp directory).


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