# File Structure

A Destination is organised into a fixed set of stage files, plus any custom HTTP endpoints you add. Every file is optional — only the ones you fill in are invoked.

{% code title="Destination layout" %}

```
playground/
├── edge/
│   ├── init         runs on the CDN edge when a visitor session starts
│   ├── tag          runs on the CDN edge for every tracked event
│   ├── user         runs on the CDN edge when user identity changes
│   └── scheduled    runs on the CDN edge on a cron schedule
├── browser/
│   ├── init         runs in the browser once on page load
│   ├── tag          runs in the browser for every tracked event
│   └── user         runs in the browser when user identity changes
└── apis/
    ├── cdn/         browser-callable HTTP endpoints
    └── server/      authenticated server-only HTTP endpoints
```

{% endcode %}

### Edge files

Edge files run on the EdgeTag CDN edge (Cloudflare Workers). They see the full request context, have access to your variables and infrastructure bindings, and can make outbound HTTP requests.

* **`edge/init`** — runs once when a visitor session starts. Use it to capture click IDs from URL parameters, detect new users, or read from the identity graph before the first event fires.
* **`edge/tag`** — runs for every tracked event (`Purchase`, `PageView`, `AddToCart`, `ViewContent`, `InitiateCheckout`, etc., and any custom events you send). This is where most Destination logic lives: forwarding events to third-party APIs, enriching payloads with server-only data, and hashing PII.
* **`edge/user`** — runs when user identity explicitly changes (login, signup, profile update). Use it to sync identity to a CRM or resolve the user against an external system.
* **`edge/scheduled`** — runs periodically on a cron schedule. Use it for batch exports, periodic syncs, or cleanup jobs.

### Browser files

Browser files run in the visitor's browser and are loaded by the EdgeTag SDK. They're the right place for anything that needs to touch the page — loading third-party scripts, calling a pixel's browser SDK, or reading values from the DOM.

* **`browser/init`** — runs once on page load. Use it to load third-party scripts (like `fbq`, `gtag`, `pintrk`), gated by consent.
* **`browser/tag`** — runs for every tracked event. Use it to call the third-party pixel's tracking API with the event data.
* **`browser/user`** — runs when the user identity changes in the browser. Use it to update the third-party pixel with user data.

{% hint style="warning" %}
Browser code runs directly on your website. Errors in this code can break site functionality. Test thoroughly before deploying.
{% endhint %}

### API endpoints

In addition to the stage files, a Destination can expose its own HTTP endpoints on your EdgeTag domain. You add them from the Playground UI, one file per endpoint.

* **CDN APIs** — browser-callable endpoints (no authentication). Use these for first-party endpoints your site or app needs to hit directly — things like `/api/subscribe` or `/api/consent-preferences`.
* **Server APIs** — authenticated endpoints that also receive `params.currentUser`. Use these for admin-only or server-to-server integrations.

Both endpoint types have access to your variables and infrastructure bindings — but not to `requestHandler` or identity-graph helpers.

### Enabled stages

Only the files you fill in are invoked. An empty `edge/scheduled`, for example, means no cron is registered at all; an empty `browser/init` means no browser bootstrapping runs. You can start with a single file (usually `edge/tag`) and add more as you need them.

{% hint style="info" %}
When you save, Playground wraps your edge code into a ServiceWorker module and your browser code into an ES module. You don't write the wrappers yourself — just the function bodies.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.edgetag.io/playground/destination/file-structure.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
