Skip to main content

Article Import API

DRE exposes three distinct article-import paths. Choose the right one for your integration:

PathServiceModeUse When
POST /pos/articles/importPOSServiceSyncPOS terminal, small batches, immediate result needed
POST /pos/articles/import-batchPOSServiceAsyncPOS-originated batches > 50 articles; monitor via ArticleImportJobs
POST /api/v1/Articles:bulk-importPublicAPIAsyncSystem integrations, large volumes (up to 10 000 rows); monitor via ImportJobs
SAP master data via DRFOUT (SOAP/REST)

The three paths above are for application-level article uploads. SAP S/4HANA master data (article/merchandise views) replicates into DRE over a separate DRFOUT inbound interface, not these endpoints. It terminates the ProductMerchandiseViewReplicationBulkRequest contract via REST at POST /api/v1/master-data/ProductMerchandiseViewReplicationBulkRequest and via native SOAP at /api/v1/master-data/soap. Auth is mTLS only. For the full envelope, field mapping, and onboarding, see the DRFOUT Master Data guide.

ImportJobs is the canonical tracking entity for PublicAPI bulk imports

For any import submitted via POST /api/v1/Articles:bulk-import (or any other bulkImport bound action on PublicAPI), poll GET /api/v1/ImportJobs/{id} for status — not ArticleImportJobs. See ImportJobs below.

ArticleImportJobs is deprecated for new integrations

GET /api/v1/ArticleImportJobs and GET /api/v1/ArticleImportJobItems track POS-originated batch imports (POST /pos/articles/import-batch) only. They are deprecated (@deprecated). For all PublicAPI bulk imports use ImportJobs + ImportJobErrors instead.

POST /api/v1/Articles:bulk-import — PublicAPI Bulk Import (canonical)

The bulkImport action is bound on every PublicAPI writable entity that supports mass-create / mass-upsert: Articles, Promotions, Budgets, Stakeholders, CouponTypes, CouponCodeConfigurations, CouponCodes, Conditions, ArticleGroups, PosGroups, PriorityGroups, MutualExclusionGroups (12 entities; each has a /<Entity>/PublicAPI.bulkImport path in the OpenAPI spec). This matches the multi-type set tracked by ImportJobs below.

This section documents the request body schema in full, so integrators do not have to reverse-engineer the shape from $metadata.

The Articles List Report upload button is not this endpoint. The Articles List Report toolbar has an importArticles custom action (a FileUploader dialog). It accepts CSV or JSON, parses the rows client-side, and POSTs them row-by-row to /admin/Articles — it is the end-user UI path, not the bulk-import API. The actual PublicAPI bulk import endpoint is documented here.

Endpoint

POST /api/v1/<Entity>:bulk-import          (REST alias — recommended)
POST /api/v1/<Entity>/PublicAPI.bulkImport (OData V4 collection-bound)
HeaderValue
Content-Typeapplication/json
AuthorizationBearer <xsuaa-jwt>
Idempotency-Keyclient-generated UUID — RECOMMENDED

Request body

{
header?: {
tenantId?: string; // override JWT tenant (admin scope only)
minorVersion?: integer; // wire-format version
continueOnError?: boolean; // false (default) = rollback on first error
idempotencyKey?: string; // alternative to Idempotency-Key header
},
rows: Array<EntityPayload>; // per-call cap: 10 000 rows
}

Each rows[] element uses the same JSON shape as a single POST /api/v1/<Entity> body. See the generated OpenAPI spec for the per-entity field list.

Example — Articles (3 rows)

POST /api/v1/Articles:bulk-import
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Idempotency-Key: a1b2c3d4-1234-5678-9abc-def012345678
Content-Type: application/json

{
"header": {
"tenantId": "tenant-a",
"continueOnError": false
},
"rows": [
{ "articleNumber": "ART-1001", "name": "Espresso 1kg", "ean": "4001234567890" },
{ "articleNumber": "ART-1002", "name": "Filter Coffee 500g", "ean": "4001234567906" },
{ "articleNumber": "ART-1003", "name": "Decaf 250g", "ean": "4001234567913" }
]
}

Response (202 Accepted)

{
"jobId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"statusUrl": "/api/v1/ImportJobs(f47ac10b-58cc-4372-a567-0e02b2c3d479)",
"minorVersion": 13
}

Poll GET statusUrl (i.e. GET /api/v1/ImportJobs({id}) — the canonical tracking entity documented below) until the job status is SUCCEEDED or FAILED. With continueOnError: true the completed job lists per-row outcomes via ImportJobErrors.

Idempotency-Key

Sending the same key twice within 24 hours returns the original jobId (200) without re-running the import. Required for at-least-once integrations where the client may retry on network failure.

Per-tenant limits

LimitValue
Rows per call10 000
Idempotency-Key retention24 h

See also: Public API Service for auth headers, error catalog, HMAC sample, and OpenAPI links.


ImportJobs + ImportJobErrors

ImportJobs is the canonical status-tracking entity for all PublicAPI bulk imports. It is multi-type: it tracks Articles, Promotions, Budgets, and every other entity with a bulkImport bound action.

GET /api/v1/ImportJobs                       — list all jobs for current tenant
GET /api/v1/ImportJobs({id}) — single job status
GET /api/v1/ImportJobErrors?$filter=job_ID eq '{id}' — per-row errors
PATCH /api/v1/ImportJobs({id}) — update callbackUrl only
DELETE /api/v1/ImportJobs({id}) — allowed for terminal jobs only (409 if still running)

POS Article Import Paths

POST /pos/articles/import

Synchronous import. Returns immediately with per-article results. Use for real-time POS terminal scenarios where the operator needs instant feedback.

POST /pos/articles/import-batch

Asynchronous batch import. Returns a jobId for monitoring. Progress is tracked via GET /admin/ArticleImportJobs({id}) (Admin Service) or GET /api/v1/ArticleImportJobs({id}) (PublicAPI).

ArticleImportJobs scope

ArticleImportJobs / ArticleImportJobItems track POS-originated batch imports only (POST /pos/articles/import-batch). They do not track PublicAPI bulk imports. These entities are deprecated for new integrations — use ImportJobs for all new PublicAPI integrations.