Skip to content

Load ProjectItems

A ProjectItem ties an Item to a Project. While Item data is global, ProjectItem data is specific to a project (e.g., a season). The same item can exist in multiple projects with different project-level property values. This is typically considered seasonal data that can change season over season — if an item is carried over into a following season, the ProjectItem data from the prior season will not necessarily be the same.

When you include PROJECT_ITEM in your loadType, the Loader will create or update ProjectItem entities into the target project.

Load Type Configuration

Include PROJECT_ITEM in the loadType array alongside ITEM:

{
  "loadType": ["ITEM", "PROJECT_ITEM"]
}

You can also combine with ASSORTMENT to load into assortments at the same time:

{
  "loadType": ["ITEM", "PROJECT_ITEM", "ASSORTMENT"]
}

Specifying the Target Project

The Loader needs to know which project to load project items into. Always specify the target project with workspaceIdentifier, even when also loading assortments.

Terminology: workspace vs project

What the UI and these docs call a "project" is, in the API, a workspace of workspaceType: 'PROJECT'. The loader resolves workspaceIdentifier by querying the workspace entity (with workspaceType: 'PROJECT') for one whose identifier matches the value you pass — not the project entity. The identifier property therefore lives on the workspace, and that is the entity you update to set it.

workspaceIdentifier (Required for PROJECT_ITEM)

Provide the workspace's identifier value in the loader configuration:

{
  "loadType": ["ITEM", "PROJECT_ITEM"],
  "workspaceIdentifier": "fall:2025"
}

The workspace must have an identifier property matching this value

The Loader resolves the target project by looking up a workspace (with workspaceType: 'PROJECT') whose identifier equals your workspaceIdentifier. If no workspace has that identifier set, or the value doesn't match exactly, the lookup fails and the project-item load is rejected with an "Unsupported access pattern" error.

Setting the identifier property on a workspace

identifier is not editable from the Hub UI. Set it with a direct PUT against the workspace entity (entityName: "workspace" via the SDK, or PUT /workspaces/{id} via REST), using the workspace's ID in the URL and the desired identifier in the body.

import { Entities } from "@contrail/sdk";

await new Entities().update({
  entityName: "workspace",
  id: "BCIzw8b7yHbS8xCN", // the workspace's ID (the project workspace)
  object: {
    identifier: "summer_2025", // must match workspaceIdentifier in your loader config
  },
});
curl --request PUT \
  --url 'https://api.vibeiq.com/prod/api/workspaces/BCIzw8b7yHbS8xCN' \
  --header 'X-Api-Key: API_KEY' \
  --header 'X-Api-Org: ORG_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "identifier": "summer_2025"
  }'

Replace the path segment (BCIzw8b7yHbS8xCN) with the workspace's actual ID, and summer_2025 with the identifier you intend to use as workspaceIdentifier. The two must match exactly. The workspace must already be of type PROJECT — the loader filters on workspaceType: 'PROJECT' during resolution.

Always pass workspaceIdentifier explicitly

Even when loading assortments alongside project items (["ITEM", "PROJECT_ITEM", "ASSORTMENT"]), pass workspaceIdentifier in your configuration rather than relying on the project workspace being inferred from the assortment's workspace.


CSV Structure

Project item CSV files use the same flat structure as item loads. Properties specific to the ProjectItem entity type are applied at the project level, while Item properties are applied globally.

Style Name,Style Number,Seasonal Status,Target Delivery
Classic Tee,STY-001,Active,2025-03-15
V-Neck Tee,STY-002,Carry Over,2025-04-01
Tank Top,STY-003,New,2025-05-15

Properties that exist on both Item and ProjectItem entity types are resolved based on the property's level designation (Family, Option, All, Override).


Complete Example

Style Name,Style Number,Seasonal Status,Target Price
Classic Tee,STY-001,Active,29.99
V-Neck Tee,STY-002,Carry Over,34.99
Tank Top,STY-003,New,24.99
{
  "loadType": ["ITEM", "PROJECT_ITEM"],
  "federatedMappings": {
    "name": "Style Name",
    "itemFamilyFederatedId": "Style Number"
  },
  "conditionalColumns": [
    {
      "toProperty": "typePath",
      "default": "item:product:apparel"
    }
  ],
  "workspaceIdentifier": "fall:2025"
}
loadType:
  - ITEM
  - PROJECT_ITEM
federatedMappings:
  name: "Style Name"
  itemFamilyFederatedId: "Style Number"
conditionalColumns:
  - toProperty: typePath
    default: "item:product:apparel"
workspaceIdentifier: "fall:2025"

For general item loading (the family/option model, required properties), see Loading Item Data. For assortment loading, see Assortments. For the full configuration reference, see Loader Configuration Reference.