Skip to main content
Every JTL integration must declare which platform resources it needs access to. The JTL Platform uses scopes; permission strings that grant read or write access to specific API resources. How you declare scopes depends on the environment:
EnvironmentWhere scopes are declaredFormat
Cloudmanifest.jsonresource.read / resource.write
OnPremiseApp registration POST requestresource.read / resource.write
In both cases, the principle of least privilege applies, meaning you should request only the scopes your app actually needs.

Cloud Scopes

For Cloud, you declare API scopes in your manifest.json under capabilities.erp.api.scopes. These scopes determine which Cloud ERP 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 and erp. This allows you to limit the resources your app can access based on what the merchant has authorized.

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", "stock.read"]
        }
      ]
    }
  }
}

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

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": [
      "return.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": [
    "stock.read",
    "stock.write",
    "items.write",
    "salesorder.read"
    "return.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 and write. If your app only needs to display data, request read scopes only. Add write scopes when your app genuinely modifies resources. Use optional scopes for progressive features (OnPremise). If your app has optional features that need extra permissions, put those scopes 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.