> ## 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.

# Scopes & Permissions

> Control what your app can access on the JTL Platform

<Warning>
  **Scope enforcement on the Cloud Platform has not shipped yet.** This is a temporary state. Current behavior: the platform validates declared scopes at registration and rejects unknown values. Future behavior (in progress): scopes are shown to the merchant at install time and the API layer rejects calls that exceed the declared set. Until enforcement ships, declared scopes do not restrict what your app can call. Declare what your app actually needs so behavior stays consistent once enforcement ships.
</Warning>

Every JTL integration must declare which platform resources it needs access to. The JTL Platform uses **scopes**: permission strings that describe the read, write, or print access an app is requesting against specific API resources.

How you declare scopes depends on the environment:

| Environment   | Where scopes are declared                  | Format                |
| ------------- | ------------------------------------------ | --------------------- |
| **Cloud**     | Manifest, in `capabilities.erp.api.scopes` | `resource.permission` |
| **OnPremise** | App registration POST request              | `resource.permission` |

In both cases, the principle of least privilege applies, meaning you should request only the scopes your app actually needs.

## Anatomy of a Scope

Every scope follows the pattern `resource.permission`.

| Component    | Description                   | Examples                                                                 |
| ------------ | ----------------------------- | ------------------------------------------------------------------------ |
| `resource`   | The API domain your app needs | `items`, `orders`, `customers`, `inventory`                              |
| `permission` | The access level              | `read` (GET), `write` (POST/PATCH/DELETE), `print` (PDF/print endpoints) |

<Note>
  Permissions do not include each other. `write` does not imply `read`, and `print` does not imply either. If your app needs to read items, modify them, and generate printed documents, declare all three: `items.read`, `items.write`, `items.print`.
</Note>

## Available Scopes

The table below is generated from the latest cloud OpenAPI spec. Any value outside this list is rejected at registration in both Cloud (manifest validation) and OnPremise (registration POST).

### Sales

| Scope                   | Description                                             |
| ----------------------- | ------------------------------------------------------- |
| `customers.read`        | Grants permission to read customer data.                |
| `customers.write`       | Grants permission to create and modify customer data.   |
| `items.read`            | Grants permission to read item data.                    |
| `items.write`           | Grants permission to create and modify item data.       |
| `orders.read`           | Grants permission to read orders.                       |
| `returns.read`          | Grants permission to read returns.                      |
| `returns.write`         | Grants permission to create and modify returns.         |
| `saleschannels.read`    | Grants permission to read sales channels.               |
| `salesorders.print`     | Grants permission to print and output sales orders.     |
| `salesorders.read`      | Grants permission to read sales orders.                 |
| `salesorders.write`     | Grants permission to create and modify sales orders.    |
| `salesquotations.print` | Grants permission to print and output sales quotations. |
| `salesquotations.read`  | Grants read access to sales quotations.                 |
| `salesquotations.write` | Grants write access to sales quotations.                |

### Inventory and Fulfilment

| Scope                 | Description                                            |
| --------------------- | ------------------------------------------------------ |
| `deliveries.read`     | Grants permission to read deliveries.                  |
| `deliveries.write`    | Grants permission to create and modify deliveries.     |
| `deliverynotes.print` | Grants permission to print and output delivery notes.  |
| `deliverynotes.read`  | Grants permission to read delivery notes.              |
| `deliverynotes.write` | Grants permission to create and modify delivery notes. |
| `inventories.read`    | Grants permission to read stock levels.                |
| `inventories.write`   | Grants permission to modify stock levels.              |
| `inventory.read`      | Grants permission to read stock levels.                |
| `inventory.write`     | Grants permission to modify stock levels.              |
| `labels.read`         | Grants permission to read labels.                      |
| `labels.write`        | Grants permission to create and modify labels.         |
| `picklists.read`      | Grants permission to read pick lists.                  |
| `picklists.write`     | Grants permission to create and modify pick lists.     |
| `warehouse.read`      | Grants permission to read warehouse data.              |

### Finance

| Scope                           | Description                                                 |
| ------------------------------- | ----------------------------------------------------------- |
| `currencies.read`               | Grants read access to currencies.                           |
| `invoices.read`                 | Grants permission to read invoices.                         |
| `invoices.write`                | Grants permission to create and modify invoices.            |
| `paymentmethods.read`           | Grants read access to payment methods.                      |
| `salesinvoicecorrections.print` | Grants permission to print and output invoice corrections.  |
| `salesinvoicecorrections.read`  | Grants permission to read invoice corrections.              |
| `salesinvoicecorrections.write` | Grants permission to create and modify invoice corrections. |
| `salesinvoices.print`           | Grants permission to print and output sales invoices.       |
| `salesinvoices.read`            | Grants read access to sales invoices.                       |
| `salesinvoices.write`           | Grants write access to sales invoices.                      |
| `taxes.read`                    | Grants permission to read tax data.                         |
| `taxes.write`                   | Grants permission to create and modify tax data.            |

### Procurement

| Scope            | Description                          |
| ---------------- | ------------------------------------ |
| `suppliers.read` | Grants permission to read suppliers. |

### System

| Scope                             | Description                                                                                 |
| --------------------------------- | ------------------------------------------------------------------------------------------- |
| `all.read`                        | Allows the application to read all data.                                                    |
| `application.runas`               | Allows the application to execute requests on behalf of another user.                       |
| `authentication.updateforeignapp` | Grants permission to update registered third-party apps.                                    |
| `customfields.read`               | Grants permission to read custom fields.                                                    |
| `customfields.write`              | Grants permission to create and modify custom fields.                                       |
| `extensibility.integration`       | Grants permission to manage extensions and integrations of the JTL-Wawi.                    |
| `foreignapps.manage`              | Grants permission to manage registered third-party apps (registration, update and removal). |
| `jera.read`                       | Grants read access to JERA internal endpoints.                                              |
| `system.config.read`              | Grants permission to read the system configuration.                                         |
| `system.config.write`             | Grants permission to modify the system configuration.                                       |
| `system.worker.read`              | Grants permission to read the configuration and status of background workers.               |
| `system.worker.write`             | Grants permission to configure and control background workers.                              |
| `wawiapp.all`                     | Grants access to Wawi app related operations.                                               |

### Other

| Scope              | Description                                                                              |
| ------------------ | ---------------------------------------------------------------------------------------- |
| `masterdata.read`  | Read master data such as shipping methods, payment methods, color codes and tax classes. |
| `masterdata.write` | Write master data                                                                        |
| `pps.read`         | Grants permission to read production data.                                               |
| `pps.write`        | Grants permission to create and modify production data.                                  |
| `resources.read`   | Grants permission to read resource management data.                                      |
| `resources.write`  | Grants permission to create and modify resource management data.                         |

## Cloud Scopes

For Cloud, you declare API scopes in your `app.json` under `capabilities.erp.api.scopes`. These scopes determine which JTL-Wawi API endpoints your app can call.

### Declaring Scopes in the Manifest

```json theme={null}
{
  "capabilities": {
    "erp": {
      "api": {
        "scopes": [
          "items.read",
          "items.write"
        ]
      }
    }
  }
}
```

Scopes follow the pattern `resource.permission`:

| Component    | Description                   | Examples                                             |
| ------------ | ----------------------------- | ---------------------------------------------------- |
| `resource`   | The API domain your app needs | `items`, `customers`, `salesorder`, `stock`          |
| `permission` | The access level              | `read` (GET requests), `write` (POST, PATCH, DELETE) |

<Note>
  Requesting `write` access does not automatically include `read`. If your app needs to both read and modify items, declare both `items.read` and `items.write`.
</Note>

### Capability-level Permissions

Beyond API scopes, Cloud Apps can enforce granular permissions on individual capabilities like **panels**. This lets you scope specific UI surfaces to a smaller subset of resources than the app as a whole.

#### Panel Permissions

Use `requiredScopes` on a panel definition to control resource access:

```json theme={null}
{
  "capabilities": {
    "erp": {
      "panel": [
        {
          "title": "Inventory Insights",
          "url": "https://example.com/panel/inventory",
          "requiredScopes": ["items.read", "inventory.read"]
        }
      ]
    }
  }
}
```

`requiredScopes` accepts the same scopes listed above.

## OnPremise Scopes

For OnPremise integrations, scopes are declared during app registration via the REST API. You include them in the `mandatoryApiScopes` and `optionalApiScopes` arrays of the registration request.

### Registering with Scopes

The example below registers an app that requires four scopes and optionally uses one more.

```bash theme={null}
curl -i -X POST \
  "http://127.0.0.1:<port>/api/eazybusiness/authentication" \
  -H "Content-Type: application/json" \
  -H "api-version: 2.0" \
  -H "x-appid: MyApp/1.0.0" \
  -H "x-appversion: 1.0.0" \
  -H "x-challengecode: MyChallengeCode" \
  -d '{
    "appId": "MyApp",
    "displayName": "My App",
    "description": "Inventory management tool",
    "version": "1.0.0",
    "providerName": "My Company",
    "providerWebsite": "https://example.com",
    "mandatoryApiScopes": [
      "stock.read",
      "stock.write",
      "items.write",
      "salesorder.read"
    ],
    "optionalApiScopes": [
      "returns.read"
    ]
  }'
```

### Fetching Registration Status and Granted Scopes

After registering, the API returns a `registrationId`. Poll the registration status endpoint with this ID to retrieve your API key and confirm which scopes were granted:

```bash theme={null}
curl -i -X GET \
  "http://127.0.0.1:64110/api/eazybusiness/authentication/{registrationId}" \
  -H "api-version: 2.0" \
  -H "x-challengecode: MyChallengeCode"
```

The response contains your API key and the scopes attached to it:

```json theme={null}
{
  "requestStatusInfo": {
    "appId": "MyApp",
    "registrationRequestId": "abc-123",
    "status": 0
  },
  "token": {
    "apiKey": "00000000-0000-0000-0000-000000000000"
  },
  "grantedScopes": [
    "inventory.read",
    "inventory.write",
    "items.write",
    "orders.read",
    "returns.read"
  ]
}
```

<Warning>
  The API key is shown **only once** in this response. Store it securely, as it cannot be retrieved again. All future API requests use this key in the `Authorization: Wawi <API-Key>` header.
</Warning>

The `grantedScopes` array tells you exactly which permissions your app received. If any of your `optionalApiScopes` were not granted, they will be absent from this array. Your app should check `grantedScopes` and adapt its functionality accordingly.

### Mandatory vs. Optional Scopes

| Field                | Description                                      |
| -------------------- | ------------------------------------------------ |
| `mandatoryApiScopes` | Scopes your app **requires** to function.        |
| `optionalApiScopes`  | Scopes your app **can use** but doesn't require. |

Use mandatory scopes for core functionality and optional scopes for enhanced features that can degrade without breaking core functionality.

## Updating Scopes After Registration

<Tabs>
  <Tab title="Cloud">
    Cloud Apps support updating scopes by modifying your `app.json`. Update the `capabilities.erp.api.scopes` array, then re-submit the updated manifest through the [Partner Portal](https://partner.jtl-cloud.com/).
  </Tab>

  <Tab title="OnPremise">
    OnPremise apps cannot modify scopes on an existing registration. If your app needs additional scopes, you must re-register the app with the updated scope list. This generates a new API key and the old key is invalidated.

    Plan your scopes carefully before initial registration. Use `optionalApiScopes` for features you may need later to avoid forcing a re-registration.
  </Tab>
</Tabs>

## Best Practices

**Request minimal scopes.** Only declare scopes your app actually uses.

**Separate read, write, and print.** If your app only displays data, request `read` only. Add `write` when your app modifies resources. Add `print` only when you need to print.

**Avoid `system.all`.** Use granular scopes wherever possible.

**Use optional scopes for progressive features (OnPremise).** If your app has optional features that need extra permissions, put those in `optionalApiScopes` so the core app still works without them.

**Document your scopes for merchants.** In your App Store listing and support docs, explain why your app needs each scope. Transparency builds trust.

**Check scopes at runtime.** Before making API calls that require specific permissions, verify your app has the necessary scope. Handle `403 Forbidden` responses by showing clear messages.

## What's Next

<CardGroup cols={2}>
  <Card title="OAuth 2.0 Flow" icon="key" href="/guides/essentials/authentication/oauth2-flow">
    Understand how tokens and scopes work together in the authentication flow.
  </Card>

  <Card title="API Keys & Tokens" icon="lock" href="/guides/essentials/authentication/api-keys-tokens">
    Reference for all credential types across Cloud, OnPremise, and SCX.
  </Card>

  <Card title="Error Handling" icon="triangle-alert" href="/guides/essentials/common-patterns/error-handling">
    Handle permission errors and scope-related 403 responses.
  </Card>

  <Card title="App Manifest Reference" icon="file-braces" href="/guides/cloud-apps/app-manifest">
    Full app.json schema including all capability fields.
  </Card>
</CardGroup>
