Authentication
DRE ships in two deployment shapes, and they authenticate differently. Choose the section that matches the instance you are connecting to:
| Target | Mechanism | Credential on the wire |
|---|---|---|
| BTP (cloud) | OAuth 2.0 client credentials via SAP XSUAA | Authorization: Bearer <jwt> |
| Local-store (on-prem / edge) | API key (POS) · session cookie (admin UI) | X-Api-Key: <key> · session cookie |
There is no inbound OAuth 2.0 token endpoint on a local-store instance. OAuth 2.0 is the BTP mechanism. (A local store does use OAuth 2.0 client credentials, but only outbound — to authenticate itself when syncing up to BTP. That is not a path integrators call.)
Connecting to a BTP (cloud) instance
The BTP deployment is secured with the SAP Authorization and Trust Management Service (XSUAA). Machine-to-machine integrators authenticate with the OAuth 2.0 client credentials grant and present the resulting JWT directly to the DRE application URL.
1. Obtain a service key
Create a service key for the DRE XSUAA service instance in your SAP BTP
subaccount (cockpit → Instances and Subscriptions, or
cf create-service-key). It contains url (the token endpoint), clientid,
and clientsecret.
2. Request an access token
curl -X POST '<xsuaa-url>/oauth/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
-d 'client_id=<clientid>' \
-d 'client_secret=<clientsecret>'
The response carries the JWT in access_token:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "bearer",
"expires_in": 14399,
"scope": "dre.POSReader"
}
3. Call DRE with the token
Present the JWT as a bearer token on every request to the DRE application URL.
The BTP application router fronts /pos and /admin and enforces XSUAA, so the
token is validated before your request reaches the engine.
# Real-time evaluation (POS Service)
curl -X POST 'https://<dre-url>/pos/v2/evaluate' \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \
-d '{ "request": { "posGroupCode": "STORE-001", "items": [ ... ] } }'
# Read promotion master data (Admin Service, OData V4)
curl -H 'Authorization: Bearer <access-token>' \
"https://<dre-url>/admin/Promotions?\$filter=status eq 'ACTIVE'"
Token refresh
Client-credentials tokens have a limited lifetime (DRE issues ~4-hour
tokens; read expires_in from the token response — do not hard-code it). Build
caching and refresh into your integration:
- Cache the token and reuse it until shortly before expiry.
- Request a fresh token before the current one expires.
- On
401 Unauthorized, refresh the token and retry once.
Roles and scopes (BTP)
Your service binding must include the scope your integration needs. Request the narrowest role that covers your use case.
| Role | Scope | Grants | Typical consumer |
|---|---|---|---|
POSReader | dre.POSReader | Evaluate / simulate / confirm, coupon ops, article import, heartbeat | POS, webshop, kiosk |
PromotionManager | dre.PromotionManager | Promotion CRUD on the Admin Service | Back-office / ERP sync |
Admin | dre.Admin | Full administrative access | Admin tooling |
The POS Service accepts POSReader or Admin; the Admin Service accepts
PromotionManager or Admin.
Connecting to a local-store instance
A local-store instance is the offline-capable derivative of DRE that runs at
or near the point of sale (its data lives in a local SQLite file, data/store.db).
It serves the same /pos endpoints as BTP, but authenticates with a POS API
key rather than XSUAA. The store's web admin UI (/local-admin) uses a
password-protected session.
POS endpoints — API key
Every request to /pos/* must carry the API key in the X-Api-Key header:
curl -X POST 'http://localhost:4004/pos/v2/evaluate' \
-H 'X-Api-Key: <pos-api-key>' \
-H 'Content-Type: application/json' \
-d '{ "request": { "posGroupCode": "STORE-001", "items": [ ... ] } }'
A missing or wrong key returns:
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}
Where the key comes from. The key is a 64-character hex string generated automatically on the store's first start-up and persisted locally. There is no CLI to create it. Retrieve or rotate it through the store's admin service (which requires a valid admin session — see below):
# Fetch the current key (POST, not GET — keeps the secret out of URL/referrer logs)
curl -X POST 'http://localhost:4004/local-admin/getApiKey' \
-b cookies.txt -H 'Content-Type: application/json' -d '{}'
# → { "apiKey": "<64-hex-characters>" }
# Rotate it (invalidates the previous key)
curl -X POST 'http://localhost:4004/local-admin/regenerateApiKey' \
-b cookies.txt -H 'Content-Type: application/json' -d '{}'
Admin UI — session login
The local admin surface (/local-admin/*) is protected by an
express-session cookie with a 30-minute idle timeout.
# First start only: set the admin password (min. 8 characters)
curl -X POST 'http://localhost:4004/local-admin/setup' \
-H 'Content-Type: application/json' \
-d '{ "password": "ChangeMe!23", "confirmPassword": "ChangeMe!23" }' \
-c cookies.txt
# Subsequent logins — store the session cookie
curl -X POST 'http://localhost:4004/local-admin/login' \
-H 'Content-Type: application/json' \
-d '{ "password": "ChangeMe!23" }' \
-c cookies.txt
# → { "success": true } (or { "redirect": "/local-admin/setup" } if no password is set yet)
There are no default admin credentials — the password must be set via
/local-admin/setup on first run. To reset a forgotten password from the
host, run the bundled CLI (or set RESET_ADMIN_PASSWORD=true to force the
setup flow on next login):
npx dre-reset-password # interactive: prompts for a new admin password
dre-config is not an auth toolThe dre-config CLI imports/exports the store's BTP-connection settings
(the outbound sync link). It does not manage the POS API key or the admin
password.
Error handling (all targets)
| HTTP status | Meaning | Action |
|---|---|---|
401 | Unauthorized | Refresh the token (BTP) or check X-Api-Key / session (local) |
403 | Forbidden | Your role/scope does not grant this operation |
429 | Rate limited | Back off and retry with exponential backoff |