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

# Workers & apps

> Deploy hosted edge workers and Vite single-page apps as part of your workspace with defineWorker and defineApp.

Cargo hosts two kinds of custom code alongside your resources: **workers** (serverless edge HTTP handlers) and **apps** (Vite single-page apps served on `*.cargo.app`). `defineWorker` and `defineApp` deploy a **source bundle directory** that Cargo Hosting builds on deploy.

## Define a worker

```ts workers/webhook.ts theme={null}
import { defineWorker, secret } from "@cargo-ai/cdk";

// bundle root needs: manifest.json + package.json + package-lock.json,
// plus a TS entry `src/index.ts` (or a pre-built `index.js`)
export const webhook = defineWorker("webhook", {
  path: new URL("./webhook", import.meta.url).pathname,
  // env vars baked into the build; secret("NAME") reads the value at deploy
  // time and stores it as a secret env var
  env: {
    CARGO_API_TOKEN: secret("CARGO_API_TOKEN"),
    LOG_LEVEL: "info",
  },
  // optional: call the worker on a schedule
  triggers: [
    {
      name: "Sync",
      cron: "@every 1h",
      path: "/cron/sync",
      data: { mode: "incremental" },
      headers: { authorization: "Bearer <something-strong>" },
    },
  ],
});
```

## Define an app

```ts apps/dashboard.ts theme={null}
import { defineApp } from "@cargo-ai/cdk";

// bundle root needs: index.html + package.json + package-lock.json (a Vite app)
export const dashboard = defineApp("dashboard", {
  path: new URL("./dashboard", import.meta.url).pathname,
});
```

The CDK validates the required bundle files exist at define time, so a missing file fails in `plan`.

<Note>
  `defineWorker`/`defineApp` are the deployable **resource** (the hosted slot).
  Author the worker's runtime code in TypeScript with `createWorker` from
  `@cargo-ai/worker-sdk` at `src/index.ts` — bundles are uploaded as source and
  built server-side: the hosting build runs `npm ci` then esbuilds the worker
  entrypoint (esbuild transpiles TypeScript natively) or `vite build` for apps.
  A pre-built `index.js` at the bundle root is still accepted for backwards
  compatibility. Bundle sub-directories have their own `package.json`, so the
  loader treats them as content to upload, not resource files to import.
</Note>

## Cron triggers

A worker can be called on a schedule: each trigger describes the full request Cargo fires — cron (or Temporal's `@every` shorthand), path, method (default `POST`), a JSON body, and headers. Set an `authorization` header and guard the route with standard Hono middleware (`bearerAuth`/`basicAuth`); ticks only fire once the worker has a promoted deployment.

Triggers can be set from the worker's page in the Cargo app, via `defineWorker` (above), or with the CLI/API:

```bash theme={null}
cargo-ai hosting worker update --uuid <workerUuid> \
  --triggers '[{"type":"cron","name":"Sync","cron":"@every 1h","path":"/cron/sync","method":"POST"}]'
```

## Calling the Cargo API

Create a workspace API token and add it to the worker as a `CARGO_API_TOKEN` secret environment variable — the Cargo API host is allowed without an `outboundAllowlist` entry. `createCargoApi(env)` from `@cargo-ai/worker-sdk` returns the fully-typed `@cargo-ai/api` client:

```ts theme={null}
import { createCargoApi } from "@cargo-ai/worker-sdk";

app.get("/workers", async (c) => {
  const api = createCargoApi(c.env);
  const { workers } = await api.hosting.worker.list();
  return c.json(workers);
});
```

## Custom integrations

A worker that serves the Custom Integration HTTP contract (`createCustomIntegration` from `@cargo-ai/worker-sdk`) can be registered in the connector catalog declaratively:

```ts theme={null}
import { defineCustomIntegration } from "@cargo-ai/cdk";

export const integration = defineCustomIntegration("my-integration", {
  worker: webhook,
});
```

## Scaffolding and deploying standalone

You can also scaffold and ship bundles directly with the CLI:

```bash theme={null}
cargo-ai hosting app init my-app          # scaffold a Vite app
cargo-ai hosting worker init my-worker    # scaffold an edge worker
cargo-ai hosting deployment create --app-uuid <uuid> --source .
cargo-ai hosting deployment promote --uuid <deployment-uuid>
```

Slugs are kebab-case and must start with a letter (`my-worker`).
