Recipe creation via API fails with 400 error due to missing required fields in payload

Attempting to automate recipe creation for our manufacturing processes using the Windchill REST API (11.2 M030), but every POST request fails with 400 Bad Request - ‘Missing required fields’. The error message doesn’t specify which fields are missing, making it impossible to debug.

Our payload structure:


POST /Windchill/servlet/odata/RecipeMgmt/Recipes
{"name": "Assembly_Process_v2", "description": "Updated assembly sequence",
 "recipeType": "Manufacturing", "status": "Draft"}

We’ve reviewed the API documentation, but it only lists ‘name’ and ‘recipeType’ as required. The UI allows recipe creation with just these fields, but the API rejects it. How can we discover the complete list of required fields for API-based recipe creation? This is blocking our process digitalization initiative.

The 400 error you’re encountering is due to incomplete understanding of the Recipe object’s validation requirements. Let me provide a complete solution addressing all three focus areas.

1. API required fields validation: The Recipe type has both explicit required fields (documented) and implicit required fields (enforced by business logic). The API performs multi-layer validation:

  • Schema validation (data types, field names)
  • Business rule validation (mandatory relationships, lifecycle constraints)
  • Type-specific validation (Recipe-specific requirements)

To see the complete validation rules, query the metadata:


GET /Windchill/servlet/odata/RecipeMgmt/$metadata
Filter on EntityType name="Recipe"

This returns the OData schema including all required properties marked with Nullable="false".

2. Recipe schema discovery: The actual required fields for Recipe creation are:

  • name (String) - Recipe identifier
  • recipeType (Enum) - Manufacturing, Assembly, Inspection, etc.
  • containerReference (Object reference) - Parent product or project
  • lifecycleState (Object) - Initial lifecycle state
  • organizationUnit (Object reference) - Owning org unit
  • creatorRole (String) - Role context for creator

Discover these dynamically:


OPTIONS /Windchill/servlet/odata/RecipeMgmt/Recipes
Response includes: Required-Fields header listing mandatory attributes

Alternatively, create a recipe via UI and capture the network traffic. The UI’s POST request reveals the complete payload structure.

3. Payload construction: Build your payload with all required fields:

{
  "name": "Assembly_Process_v2",
  "description": "Updated assembly sequence",
  "recipeType": "Manufacturing",
  "containerReference": {
    "@odata.id": "Products('OR:wt.part.WTPart:123456')"
  },
  "lifecycleState": {
    "@odata.id": "LifecycleStates('OR:wt.lifecycle.State:789')"
  },
  "organizationUnit": {
    "@odata.id": "OrgUnits('OR:wt.org.WTOrganization:456')"
  },
  "creatorRole": "DESIGNER",
  "owner": {
    "@odata.id": "Users('demo.user')"
  }
}

Step-by-step resolution:

  1. Discover container context: Recipes must belong to a product or project. Query available containers:

GET /Windchill/servlet/odata/ProdMgmt/Products
Select a product OID to use as containerReference
  1. Get default lifecycle state: Recipes require an initial lifecycle state:

GET /Windchill/servlet/odata/LifecycleMgmt/LifecycleTemplates?$filter=name eq 'Recipe'
Expand the template to get the initial state OID
  1. Determine organization unit: Query your user’s default org unit:

GET /Windchill/servlet/odata/OrgMgmt/Users('your.username')?$expand=DefaultOrganization
Extract the organization OID
  1. Construct complete payload: Combine all required references into your POST request.

Validation debugging technique: Use partial payload testing:


// Test 1: Minimal documented fields
{"name": "Test", "recipeType": "Manufacturing"}
// Note which field is reported missing

// Test 2: Add container
{...previous fields..., "containerReference": {...}}
// Continue adding fields until validation passes

Production-ready payload template:

{
  "@odata.type": "#PTC.RecipeMgmt.Recipe",
  "name": "Assembly_Process_v2",
  "description": "Updated assembly sequence",
  "recipeType": "Manufacturing",
  "version": "A",
  "containerReference": {"@odata.id": "Products('OR:wt.part.WTPart:123456')"},
  "lifecycleState": {"@odata.id": "LifecycleStates('OR:wt.lifecycle.State:789')"},
  "organizationUnit": {"@odata.id": "OrgUnits('OR:wt.org.WTOrganization:456')"},
  "creatorRole": "DESIGNER",
  "owner": {"@odata.id": "Users('demo.user')"},
  "folder": {"@odata.id": "Folders('OR:wt.folder.Cabinet:default')"},
  "teamTemplate": {"@odata.id": "TeamTemplates('OR:wt.team.TeamTemplate:default')"}
}

The @odata.type hint helps the API correctly identify the entity type. The version field (defaults to “A” if omitted) should be explicit. Folder and teamTemplate references ensure proper access control setup.

Test this payload structure first with a single recipe creation, then scale to your batch automation process.

The API documentation is often incomplete for complex object types like recipes. Try using the OPTIONS method on the endpoint to get the schema definition. Send OPTIONS /Windchill/servlet/odata/RecipeMgmt/Recipes and check the response for required field metadata.

Another possibility: the Recipe type might have custom required attributes defined in your organization’s type extensions. Standard Windchill recipes might only require name and type, but if your admins added mandatory custom fields, those won’t show up in the generic API documentation. Query your type definition: GET /Windchill/servlet/odata/ProdMgmt/TypeDefinitions?$filter=name eq ‘Recipe’ to see all required attributes.

Recipes have dependencies on other objects that aren’t obvious. You likely need to specify a container context (like a product or project), an owner, and possibly a lifecycle state. Try adding these to your payload: “containerRef”: “OR:container_oid”, “owner”: “username”, “state”: “INWORK”.

Check the Windchill method server logs when the API call fails. The server-side validation logs usually contain detailed information about which specific fields are missing or invalid. Look for entries with ‘ValidationException’ or ‘RequiredFieldException’ in MethodServer.log. That will tell you exactly what the API expects.

We ran into this exact issue. The problem is that the Recipe object type has mandatory relationships that must be established at creation time. You can’t create a standalone recipe - it needs to be linked to a manufacturing context or product structure. Try creating the recipe as a child of an existing product: POST to /Windchill/servlet/odata/ProdMgmt/Products(‘OR:123’)/Recipes instead of the root Recipes endpoint.