> ## 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                                                |
| ----------------------- | ---------------------------------------------------------- |
| `cusomters.read`        | Read customers (note: typo in upstream scope name)         |
| `customers.read`        | Read customer records                                      |
| `customers.write`       | Create or modify customer records                          |
| `items.read`            | Read product items, variants, and catalog data             |
| `items.write`           | Create or modify product items, variants, and catalog data |
| `offers.print`          | Print offers and quotations                                |
| `offers.read`           | Read offers and quotations                                 |
| `orders.read`           | Read orders                                                |
| `returns.read`          | Read return records                                        |
| `returns.write`         | Create or modify return records                            |
| `saleschannels.read`    | Read sales channels                                        |
| `salesorders.print`     | Print sales orders                                         |
| `salesorders.read`      | Read sales orders                                          |
| `salesorders.write`     | Create or modify sales orders                              |
| `salesquotations.read`  | Read sales quotations                                      |
| `salesquotations.write` | Create or modify sales quotations                          |

### Inventory and Fulfilment

| Scope                 | Description                                 |
| --------------------- | ------------------------------------------- |
| `deliveries.read`     | Read delivery and shipment data             |
| `deliveries.write`    | Create or modify delivery and shipment data |
| `deliverynotes.print` | Print delivery notes                        |
| `deliverynotes.read`  | Read delivery notes                         |
| `deliverynotes.write` | Create or modify delivery notes             |
| `inventories.read`    | Read inventory and stock data               |
| `inventories.write`   | Create or modify inventory and stock data   |
| `inventory.read`      | Read stock levels                           |
| `inventory.write`     | Create or modify stock levels               |
| `labels.read`         | Read labels                                 |
| `labels.write`        | Create or modify labels                     |
| `picklists.read`      | Read picklists                              |
| `picklists.write`     | Create or modify picklists                  |
| `warehouse.read`      | Read warehouse data                         |

### Finance

| Scope                           | Description                                |
| ------------------------------- | ------------------------------------------ |
| `accountings.read`              | Read accounting data                       |
| `currencies.read`               | Read currencies                            |
| `invoices.print`                | Print invoices                             |
| `invoices.read`                 | Read invoices                              |
| `invoices.write`                | Create or modify invoices                  |
| `paymentmethods.read`           | Read payment methods                       |
| `salesinvoicecorrections.print` | Print sales-invoice corrections            |
| `salesinvoicecorrections.read`  | Read sales-invoice corrections             |
| `salesinvoicecorrections.write` | Create or modify sales-invoice corrections |
| `salesinvoices.read`            | Read sales invoices                        |
| `salesinvoices.write`           | Create or modify sales invoices            |
| `taxes.read`                    | Read taxes                                 |
| `taxes.write`                   | Create or modify taxes                     |

### Procurement

| Scope            | Description           |
| ---------------- | --------------------- |
| `suppliers.read` | Read supplier records |

### System

| Scope                       | Description                               |
| --------------------------- | ----------------------------------------- |
| `all.read`                  | Read access to all data                   |
| `application.runas`         | Run requests on behalf of another user    |
| `customfields.read`         | Read custom fields                        |
| `customfields.write`        | Create or modify custom fields            |
| `extensibility.integration` | Use the extensibility integration surface |
| `jera.read`                 | Read JERA-internal endpoints              |
| `system.config.read`        | Read system configuration                 |
| `system.config.write`       | Create or modify system configuration     |
| `system.read`               | Read system data                          |
| `system.worker.read`        | Read worker synchronizations              |
| `system.worker.write`       | Create or modify worker synchronizations  |
| `wawiapp.all`               | Full access to Wawi-App operations        |

### Other

| Scope             | Description                      |
| ----------------- | -------------------------------- |
| `payments.write`  | Create or modify payments        |
| `pps.read`        | Read production data             |
| `pps.write`       | Create or modify production data |
| `resources.read`  | Read resources                   |
| `resources.write` | Create or modify resources       |

## Cloud Scopes

For Cloud, you declare API scopes in your `manifest.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 **panes**. This lets you scope specific UI surfaces to a smaller subset of resources than the app as a whole.

#### Pane Permissions

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

```json theme={null}
{
  "capabilities": {
    "erp": {
      "pane": [
        {
          "title": "Inventory Insights",
          "url": "https://example.com/pane/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 `manifest.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-code-2" href="/guides/cloud-apps/app-shell-ui-integration#app-manifest">
    Full manifest.json schema including all capability fields.
  </Card>
</CardGroup>
