The App Manifest
manifest.json is the declarative source of truth for your entire app. It lives in the root of your app repository, is updated by the CLI, and every epilot app deploy syncs the platform to exactly what it declares โ components and functions not in the manifest are removed from the deployed version.
manifest.json
{
"$schema": "https://cdn.app.sls.epilot.io/v1/schema.json",
"manifest_version": 1,
"app_id": "b1b9โฆ",
"name": "My Integration",
"description": { "de": "Beschreibung (Pflicht)", "en": "Optional English description" },
"category": "integration",
"author": { "company": "ACME GmbH", "name": "Jane Doe", "email": "dev@acme.example" },
"documentation_url": "https://docs.acme.example",
"support_email": "support@acme.example",
"pricing": { "pricing_type": "FREE" },
"notifications": { "email": "dev@acme.example", "events": ["app.installed", "app.uninstalled"] },
"permissions": [
{ "action": "entity:view", "resource": "opportunity" }
],
"assets": { "logo": "./assets/logo.png" },
"functions": [
{
"name": "sync-things",
"type": "scheduled",
"handler": "./functions/sync-things/dist/handler.js",
"schedule": "rate(30 minutes)"
}
],
"components": [
{
"id": "4f3cโฆ",
"component_type": "CUSTOM_CAPABILITY",
"name": { "de": "Mein Tab" },
"configuration": { "type": "tab", "allowed_schemas": ["opportunity"] },
"surfaces": { "capability_config": { "app_url": "./components/my-tab/dist/index.html" } },
"assets": { "zip": "./components/my-tab/dist/" }
}
]
}
The $schema reference gives you validation and autocompletion in editors like VS Code.
Top-level fieldsโ
| Field | Required | Description |
|---|---|---|
manifest_version | โ | Always 1 |
app_id | โ | Set automatically after the first deploy โ never set it by hand |
name | โ | App name shown everywhere |
description | โ | de is required; en optional |
category | โ | Marketplace category, e.g. integration |
author | โ | company required when set |
pricing | โ | FREE, SUBSCRIPTION, USAGE_BASED, ONE_TIME, CUSTOM |
notifications | โ | Email + events (app.installed, app.uninstalled) you want to be notified about |
permissions | โ | The grants your app's server-side code needs โ shown to the installing org for consent, see Permissions |
blueprint | โ | manifest_id of a blueprint to install alongside the app |
assets.logo | โ | Local path to the app logo, uploaded on deploy |
functions | โ | Server-side functions (workflow actions and cron), see below |
components | โ | The app's components (may be empty) |
The functions blockโ
| Field | Required | Description |
|---|---|---|
name | โ | Unique kebab-case identifier (max 64 chars) โ treat it as a public contract |
type | โ | workflow (flow builder action) or scheduled (cron per installation) |
handler | โ | Local path to the built JavaScript file โ inlined as code on deploy |
label | โ | Display name (TranslatedString) shown to org admins, e.g. in the flow builder picker |
description | โ | TranslatedString |
schedule | scheduled | 5-field cron or rate(...) โ see Scheduled Functions |
schedule_timezone | โ | IANA timezone for cron evaluation (default Europe/Berlin) |
secrets | โ | Keys of secret options to decrypt into input.app_options โ prefer the API Proxy instead |
wait_for_callback | โ | Workflow only โ pause the flow until your system calls back |
assets.zip | โ | Workflow only โ built config UI shown in the flow builder |
Limits: at most 10 functions per app, at most 5 of them scheduled, 300 KB code per function.
Local-only fieldsโ
Some fields exist only for the CLI and are never sent to the platform:
_diron components โ maps a component to its directory undercomponents/handlerandassetspaths โ resolved and uploaded/inlined at deploy time- Secret option values are never in the manifest; installing orgs enter them per installation
Golden rulesโ
- The manifest wins. Deploy is a sync, not a merge โ what's not declared gets removed from the version.
- Don't hand-edit
app_idor componentids of deployed components; they are identity. description.deis always required โ the platform's primary market is German-speaking.- Validate before deploying:
npx @epilot/cli app validateruns the same checks as the platform.