Skip to main content

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โ€‹

FieldRequiredDescription
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โ€‹

FieldRequiredDescription
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
schedulescheduled5-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:

  • _dir on components โ€” maps a component to its directory under components/
  • handler and assets paths โ€” resolved and uploaded/inlined at deploy time
  • Secret option values are never in the manifest; installing orgs enter them per installation

Golden rulesโ€‹

  1. The manifest wins. Deploy is a sync, not a merge โ€” what's not declared gets removed from the version.
  2. Don't hand-edit app_id or component ids of deployed components; they are identity.
  3. description.de is always required โ€” the platform's primary market is German-speaking.
  4. Validate before deploying: npx @epilot/cli app validate runs the same checks as the platform.