Skip to main content
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.
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:
EnvironmentWhere scopes are declaredFormat
CloudManifest, in capabilities.erp.api.scopesresource.permission
OnPremiseApp registration POST requestresource.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.
ComponentDescriptionExamples
resourceThe API domain your app needsitems, orders, customers, inventory
permissionThe access levelread (GET), write (POST/PATCH/DELETE), print (PDF/print endpoints)
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.

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

ScopeDescription
cusomters.readRead customers (note: typo in upstream scope name)
customers.readRead customer records
customers.writeCreate or modify customer records
items.readRead product items, variants, and catalog data
items.writeCreate or modify product items, variants, and catalog data
offers.printPrint offers and quotations
offers.readRead offers and quotations
orders.readRead orders
returns.readRead return records
returns.writeCreate or modify return records
saleschannels.readRead sales channels
salesorders.printPrint sales orders
salesorders.readRead sales orders
salesorders.writeCreate or modify sales orders
salesquotations.readRead sales quotations
salesquotations.writeCreate or modify sales quotations

Inventory and Fulfilment

ScopeDescription
deliveries.readRead delivery and shipment data
deliveries.writeCreate or modify delivery and shipment data
deliverynotes.printPrint delivery notes
deliverynotes.readRead delivery notes
deliverynotes.writeCreate or modify delivery notes
inventories.readRead inventory and stock data
inventories.writeCreate or modify inventory and stock data
labels.readRead labels
labels.writeCreate or modify labels
picklists.readRead picklists
picklists.writeCreate or modify picklists
warehouse.readRead warehouse data

Finance

ScopeDescription
accountings.readRead accounting data
currencies.readRead currencies
invoices.printPrint invoices
invoices.readRead invoices
invoices.writeCreate or modify invoices
paymentmethods.readRead payment methods
salesinvoicecorrections.printPrint sales-invoice corrections
salesinvoicecorrections.readRead sales-invoice corrections
salesinvoicecorrections.writeCreate or modify sales-invoice corrections
salesinvoices.readRead sales invoices
salesinvoices.writeCreate or modify sales invoices
taxes.readRead taxes

Procurement

ScopeDescription
suppliers.readRead supplier records

System

ScopeDescription
all.readRead access to all data
application.runasRun requests on behalf of another user
customfields.readRead custom fields
customfields.writeCreate or modify custom fields
extensibility.integrationUse the extensibility integration surface
jera.readRead JERA-internal endpoints
system.config.readRead system configuration
system.config.writeModify system configuration
system.readRead general system data
system.worker.readRead background-worker status and history
system.worker.writeCreate or modify background-worker jobs
wawiapp.allAccess all Wawi-App related operations

Other

ScopeDescription
payments.writeCreate or modify payments
pps.readRead pps
pps.writeCreate or modify pps
resources.readRead resources
resources.writeCreate 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

{
  "capabilities": {
    "erp": {
      "api": {
        "scopes": [
          "items.read",
          "items.write"
        ]
      }
    }
  }
}
Scopes follow the pattern resource.permission:
ComponentDescriptionExamples
resourceThe API domain your app needsitems, customers, salesorder, stock
permissionThe access levelread (GET requests), write (POST, PATCH, DELETE)
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.

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:
{
  "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.
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:
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:
{
  "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"
  ]
}
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.
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

FieldDescription
mandatoryApiScopesScopes your app requires to function.
optionalApiScopesScopes 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

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.

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

OAuth 2.0 Flow

Understand how tokens and scopes work together in the authentication flow.

API Keys & Tokens

Reference for all credential types across Cloud, OnPremise, and SCX.

Error Handling

Handle permission errors and scope-related 403 responses.

App Manifest Reference

Full manifest.json schema including all capability fields.