Bulk material creation via REST API fails with duplicate material errors

We’re integrating our ERP system with Smart Factory 2021.1 and running into issues with bulk material creation. When posting a batch of 50+ new materials through the REST API, about 30% fail with 409 Conflict errors claiming duplicates exist.

The error handling isn’t clear on which specific materials are duplicates. We’re also unsure if the API supports idempotent operations for material creation.

POST /api/materials/batch
{"materials": [{"code": "MAT-001", "name": "Steel Plate"}, ...]}
Response: 409 {"error": "Duplicate materials detected"}

How can we parse the 409 response to identify which materials already exist? Is there a way to make the batch operation continue processing valid materials even when some are duplicates?

Here’s the complete solution addressing all three focus areas:

Batch API Error Handling: The 409 response in Smart Factory 2021.1 includes a details array in the response body (not headers). Parse it to identify specific duplicates:

{"error": "Duplicate materials", "details": [
  {"code": "MAT-001", "reason": "exists"},
  {"code": "MAT-005", "reason": "exists"}
]}

Idempotency for Material Creation: Implement a three-tier strategy:

  1. Pre-validation: GET /api/materials/validate with material codes to check existence before batch submission
  2. Batch with skipExisting: Include "options": {"skipExisting": true, "returnAll": true} in your batch payload. The returnAll flag ensures you get both new and existing material IDs in the response
  3. Idempotent retry: Use PUT /api/materials/{code} instead of POST for individual materials-PUT creates if missing, updates if exists

409 Conflict Response Parsing: The response structure varies by endpoint. For batch operations, the details array maps to your input array indices. For individual operations, check the conflictingResource field:

{"error": "Conflict", "conflictingResource": "/api/materials/MAT-001", "existingSince": "2025-03-10T08:00:00Z"}

Implementation pattern:

try {
  response = await POST('/api/materials/batch', {
    materials: materials,
    options: {skipExisting: true, returnAll: true}
  });
} catch (error) {
  if (error.status === 409) {
    duplicates = error.body.details.map(d => d.code);
    newMaterials = materials.filter(m => !duplicates.includes(m.code));
    // Retry with filtered list
  }
}

Additional Considerations:

  • Enable API request logging with X-Debug-Mode: true header to see detailed validation failures
  • Use batch size of 25-30 materials max to avoid timeout issues
  • Implement distributed locking (Redis/database) for concurrent ERP integrations to prevent race conditions
  • The skipExisting option was added in 2021.1 SP2-verify your patch level

This approach reduced our duplicate errors from 30% to zero and handles concurrent operations gracefully. The pre-validation step adds ~200ms overhead but eliminates retry cycles.

Thanks for the suggestions. The X-Duplicate-Material-Codes header isn’t present in our responses-might be a version-specific feature. The two-phase approach makes sense but seems inefficient for large batches. Is there a way to configure the batch endpoint to skip duplicates and continue processing?

The batch endpoint doesn’t provide granular error details by default in 2021.1. You’ll need to switch to individual POST operations with proper error handling to identify specific duplicates. Check the response headers for the X-Duplicate-Material-Codes field-it should list the conflicting codes.