# Manifest

Atrium app developer spec, section 2: Manifest.

Declare how COHO talks to your process. Runtime paths are relative to your
registered **base URL**. Browser-facing paths are relative to
`config.browserBaseUrl` when supplied.

```json
{
  "manifestVersion": 1,
  "health": { "path": "/health", "method": "GET" },
  "config": {
    "mode": "native+embedded+external",
    "browserBaseUrl": null,
    "externalConfigureUrl": "/configure",
    "schemaPath": "/config/schema",
    "getPath": "/config",
    "putPath": "/config",
    "quickViewPath": "/ui",
    "openPresentation": "modal"
  },
  "requestedCapabilities": ["conversations.read", "conversations.write"],
  "triggers": {
    "lifecycle": {
      "setupPath": "/webhooks/atrium/setup",
      "disconnectPath": "/webhooks/atrium/disconnect"
    },
    "schedules": [],
    "events": [
      { "key": "tenancy.started", "path": "/webhooks/atrium/triggers/event" }
    ]
  },
  "operations": [
    {
      "name": "list",
      "path": "/operations/list",
      "method": "GET",
      "description": "List records for the organisation",
      "effect": "read"
    }
  ]
}
```

This sample is a **web app** (quick view). That is the default for almost every product. Match `samples/hello-node/manifest.example.json` (or hello-python / hello-go / hello-dotnet in atrium-app-samples). Starter manifests may still say `"mode": "both"` — that is the legacy spelling of native + external for the same web-app surface; `"native+embedded+external"` here is the explicit form. Do **not** start from a null `quickViewPath` unless you have confirmed a true background agent — then use `samples/hello-agent-node` and read its README (§6).

| Field | Meaning |
|---|---|
| `health.path` | Unsigned `GET`. See §4. |
| `triggers.lifecycle.setupPath` | Signed `POST` on connect. **Must return 2xx** or connect rolls back. |
| `triggers.lifecycle.disconnectPath` | Signed `POST` after credentials are revoked (best-effort). Delete org-scoped data. |
| `triggers.schedules` | Opt-in. Empty = COHO will not tick you on a cron. Each entry: `key`, `cron` (5-field: minute hour day-of-month month day-of-week; `*`, lists, ranges, steps), `timezone` (IANA, default UTC), `path`. **Private / unreviewed apps:** at most 4 schedules, and no denser than hourly (minute field must be a single value). Reviewed public listings are not capped this way. |
| `triggers.events` | Opt-in. Unknown keys are ignored until COHO supports them. |
| `requestedCapabilities` | Catalogue scope ids the app requires (e.g. `conversations.write`). Legacy short names still expand. Connect fails if the connecting person cannot grant every resolved scope. See §8. |
| `operations` | Optional. Named endpoints COHO may call on your app through the app-operations gateway (Public API + MCP). See §3.5. Omit or `[]` when unused. |
| `runtimeEnv` | Optional. Declared Hosting runtime env keys: `[{ "name", "secret", "description", "required" }]`. Values are set via the runtime-env API, not in the manifest. Required keys must be set before a Ready hosted app re-provisions. See [Runtime secrets (Hosting)](#runtime-secrets-hosting). |
| `config.schemaPath` / `getPath` / `putPath` | Optional app-owned **light** prefs only (a handful of scalars). Store proxies signed GET/PUT. Omit when unused. Serious UI is quick view, not this form. |
| `config.browserBaseUrl` | Public HTTPS origin for hosted app UI. Runtime webhooks and config remain on the private registered base URL. |
| `config.externalConfigureUrl` | Optional new-tab configure path on the browser base URL. |
| `config.quickViewPath` | In-COHO iframe path. **Default for almost all apps.** Omit only for rare background agents (webhooks + API + optional light prefs). See §6. |
| `config.openPresentation` | When `quickViewPath` is set: `full` \| `modal` \| `side`. Store defaults to `modal` if omitted. |

`config.mode` is one or more of `native`, `external`, `embedded`, joined with `+` when combined (for example `native+embedded`). The legacy value `both` means native + external.

Browser URLs are HTTPS only in non-local environments. Self-host runtime base
URLs are also HTTPS; COHO Hosting may mint a private HTTP runtime base URL
inside the VPC.
