> ## Documentation Index
> Fetch the complete documentation index at: https://developer.jtl-software.com/llms.txt
> Use this file to discover all available pages before exploring further.

# App Manifest

> The technical manifest that registers your app: identity, lifecycle, and capabilities.

The app manifest is a JSON document that registers your app with JTL. It declares the app's identity, the URL JTL loads during setup, and the capabilities through which your app integrates with the platform.

You register your app by pasting this manifest into the **JSON Code Editor** in the [Partner Portal](https://partner.jtl-cloud.com/) under **Manage apps**. You can also register an app using the registration wizard form directly.

## Top-level Fields

Two fields identify the app and its release.

| Property        | Type   | Required | Description                                                                                       |
| --------------- | ------ | -------- | ------------------------------------------------------------------------------------------------- |
| `technicalName` | string | Yes      | Stable internal identifier for the app. Max 100 characters. Used as a fallback display name.      |
| `version`       | string | Yes      | App release version. Strict semver, digits only (e.g. `1.0.0`). Pre-release tags are not allowed. |

## Lifecycle

The lifecycle object defines the URL JTL loads when a merchant installs your app.

| Property                     | Type   | Required | Description                                                                                                                              |
| ---------------------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `lifecycle.configurationUrl` | string | No       | URL rendered in an iframe during setup. Use it to present setup UI, complete the AppBridge handshake, and persist the tenant connection. |

The URL must be a standard `http://` or `https://` URL.

<Note>
  The manifest validator accepts `{metadata.*}` placeholders in this URL, but JTL does not substitute them at runtime. Use a static URL, and encode any app identity you need directly in the path or query string.
</Note>

### Identifying the App

If you publish multiple apps, each one needs its own `configurationUrl`. Two apps sharing the same URL cause the wrong setup UI to render when a merchant installs either one.

Give each app a distinct URL, either with a separate route:

```json theme={null}
"lifecycle": {
  "configurationUrl": "https://example.com/setup/inventory-sync"
}
```

Or by encoding the app's identity in the query string:

```json theme={null}
"lifecycle": {
  "configurationUrl": "https://example.com/setup?app=inventory-sync"
}
```

Use separate routes if you control routing and want cleaner URLs. Use query parameters if you prefer a single handler that switches behavior based on the app.

<Tip>
  A working configuration flow is included when you create an app with the CLI, `npm create @jtl-software/cloud-app@latest`.
</Tip>

## Capabilities

Capabilities define where and how your app integrates with JTL. Each key under `capabilities` maps to a surface. See [Architecture Overview](/guides/cloud-apps/architecture-overview) for a description of each integration type.

### Hub

Controls how the app appears in the JTL Hub dashboard. When a merchant clicks the app's card, the platform redirects to this URL.

| Property                                   | Type   | Required                     | Description                                                           |
| ------------------------------------------ | ------ | ---------------------------- | --------------------------------------------------------------------- |
| `capabilities.hub.appLauncher.redirectUrl` | string | Required if `hub` is present | URL the platform redirects to when the app card is clicked in the Hub |

Without a `redirectUrl`, the app card has no destination.

### ERP Menu Items

Add entries to the ERP Cloud sidebar under the **App** section. Each menu item links to a page in your app, loaded inside the ERP iframe.

| Property | Type   | Required | Description                                  |
| -------- | ------ | -------- | -------------------------------------------- |
| `id`     | string | Yes      | Stable internal identifier for the menu item |
| `name`   | string | Yes      | Display name shown in the navigation         |
| `url`    | string | Yes      | URL loaded when the item is clicked          |

### ERP API Scopes

Declare the JTL-Wawi API resources your app intends to use. Declared scopes are validated against the allowed list at registration.

| Property                      | Type            | Required | Description                            |
| ----------------------------- | --------------- | -------- | -------------------------------------- |
| `capabilities.erp.api.scopes` | array of string | No       | API permission scopes the app requests |

Scope values come from a fixed list, and any value outside it is rejected at registration. A subset for reference:

```json theme={null}
"scopes": [
  "items.read", "items.write",
  "orders.read", "orders.write",
  "customers.read", "customers.write",
  "inventory.read", "inventory.write"
]
```

<Note>
  Runtime enforcement of these scopes has not shipped yet, so declaring a scope here does not currently restrict what your app can call. Once enforcement is live, the API will reject calls that exceed the declared set, and the merchant will see the declared scopes at install time. See [Scopes & Permissions](/guides/essentials/authentication/scopes-permissions) for the current list.
</Note>

### ERP Panel

Add a sidebar panel that appears alongside an ERP view. Panels are context-aware and show only on matching pages. When more than one installed app targets the same view, each app renders as a tab within the panel, and tabs beyond the panel width collapse into an overflow menu.

| Property         | Type            | Required | Description                                                                                        |
| ---------------- | --------------- | -------- | -------------------------------------------------------------------------------------------------- |
| `id`             | string          | No       | Internal identifier for the panel                                                                  |
| `context`        | string          | Yes      | View path where the panel appears, in the form `$tenantSlug.<view>` (e.g. `$tenantSlug.customers`) |
| `url`            | string          | Yes      | URL loaded inside the panel iframe                                                                 |
| `requiredScopes` | array of string | No       | Per-panel scope override, using the same scope values as `capabilities.erp.api.scopes`             |

For reading the current entity in a panel, see [Reading Panel Context](/guides/cloud-apps/app-shell-ui-integration#reading-panel-context).

## Complete Example

A manifest declaring a Hub redirect, one ERP menu item, three API scopes, and one panel on the customers view:

```json theme={null}
{
  "version": "1.0.0",
  "technicalName": "my-example-app",
  "lifecycle": {
    "configurationUrl": "https://example.com/configure"
  },
  "capabilities": {
    "hub": {
      "appLauncher": {
        "redirectUrl": "https://example.com/hub/launch"
      }
    },
    "erp": {
      "menuItems": [
        {
          "id": "menu-item-1",
          "name": "Mein Menüpunkt",
          "url": "https://example.com/erp/menu"
        }
      ],
      "api": {
        "scopes": ["orders.read", "orders.write", "items.read"]
      },
      "panel": [
        {
          "id": "panel-1",
          "context": "$tenantSlug.customers",
          "url": "https://example.com/erp/pane/customers",
          "requiredScopes": ["customers.read"]
        }
      ]
    }
  }
}
```

## What's Next?

<CardGroup cols={2}>
  <Card title="Listing Manifest" icon="store" href="/guides/cloud-apps/listing-manifest">
    Define how your app appears in the App Store or is shared privately.
  </Card>

  <Card title="App Shell & UI" icon="app-window" href="/guides/cloud-apps/app-shell-ui-integration">
    Communicate with the host using AppBridge, and build UI with Platform UI components.
  </Card>
</CardGroup>
