Creating items

Load your catalogue so orders, cartonization and customs have something to resolve against.

Overview

An Item is a product record in ShipGenius, keyed by your own sku. Items are what order lines point at, what cartonization measures, and what customs declarations are built from — so creating them accurately up front removes work from every order that follows.

item.create takes a list, so a catalogue import is one call rather than one call per SKU.

Creating items

mutation CreateItems($data: [ItemInput!]!) {
    item {
        create(data: $data) {
            id
            sku
            description
        }
    }
}
{
    "data": [
        {
            "sku": "WIDGET-BLUE-01",
            "description": "Blue widget, 1 lb",
            "upc": "0123456789012",
            "unit_of_measure": "EACH",
            "item_type": "PRODUCT",
            "weight": { "measure": 1.0, "unit": "LBS" },
            "length": { "measure": 6, "unit": "IN" },
            "width": { "measure": 4, "unit": "IN" },
            "height": { "measure": 2, "unit": "IN" }
        }
    ]
}

Required fields

Two fields are required. The optional ones below feed rating, cartonization and customs.

FieldTypeRequiredDescription
skuString!YesYour identifier for the product. Must be unique.
descriptionString!YesHuman-readable description, used on customs forms.

Optional fields

FieldTypeDescription
weightWeightInputmeasure plus a unit of LBS, OZ, KG, G, TON or MT. Without it, rates fall back to package-level weight only.
length width heightLengthInputmeasure plus a unit of IN, FT, YD, CM, MM, M, DM or THOU. Required for cartonization to pick a box.
upcStringUsed to match inbound marketplace orders to this item.
unit_of_measureItemUnitOfMeasureEACH, ROLL, SHEET, PACK, BOX, CASE. Defaults to EACH.
item_typeItemTypePRODUCT, RAW_MATERIAL, CONSUMABLE, COMPONENT, EQUIPMENT, VIRTUAL. Defaults to PRODUCT.
case_quantity pallet_quantityIntUnits per case and per pallet, for bulk fulfillment.
consumable_idIDLinks the item to a Consumable it draws down.

NOTE

Dimensions and weight are a measure plus a unit, so values can be sent in whatever unit your system stores them in.

Prices and customs in one call

item_pricing and item_customs are accepted inline on ItemInput, so an item can be created complete rather than created and then amended.

{
    "data": [
        {
            "sku": "WIDGET-BLUE-01",
            "description": "Blue widget, 1 lb",
            "item_pricing": [{ "active": true, "price_type": "MSRP", "price": "24.99" }],
            "item_customs": {
                "customs_information": {
                    "name": "Blue widget",
                    "description": "Injection-moulded plastic widget",
                    "hs_code": "3926909990",
                    "country_of_origin": "US"
                }
            }
        }
    ]
}

Two notes on these shapes:

  • item_pricing is a list of InlineItemPriceInput, which requires active, price_type and price, where price_type is MSRP or COST. There is no currency field — pricing is in the account's currency.
  • item_customs is a ItemCustomsInputSpecification, a wrapper holding either customs_information (new customs data) or item_customs_id (reference an existing record). Referencing an existing record shares one classification across every SKU that uses it:
{
    "item_customs": { "item_customs_id": "5e7a131e-a21e-47f8-a09b-7abb92a2bca7" }
}

ItemCustomsInput requires name, description and hs_code. This per-commodity data is what customs declarations are built from — a customs blueprint does not supply it.

If you need to change either later, each has its own namespace:

Aliases

An alias is an alternative SKU that resolves to the same item — a marketplace's own identifier, a legacy code, a distributor part number. Aliases let inbound orders match without rewriting the incoming payload.

mutation CreateItemAliases($data: [ItemAliasInput!]!) {
    item {
        item_alias {
            create(data: $data) {
                id
                alias
            }
        }
    }
}

Updating and deleting

item.update takes ItemUpdateInput, which carries the id and only the fields you want changed. Omitted fields are left alone.

mutation UpdateItems($data: [ItemUpdateInput!]!) {
    item {
        update(data: $data) {
            id
            sku
        }
    }
}

item.delete takes a list of ids and returns the number of rows removed:

mutation DeleteItems($item_id: [ID!]!) {
    item {
        delete(item_id: $item_id)
    }
}

WARNING

Deleting an item that historical orders reference will fail. Items are referenced by order lines, so retire them by removing them from your feed rather than deleting.

Bundles

An item bundle is a set of items sold as one unit. Bundles live under their own namespace and reference items you have already created:

When an order line names a bundle, fulfillment expands it into its component items.

Finding items again

Items are searchable through the search API under the ITEM entity type:

query FindItems($search: PaginatedSearchQuery) {
    searches {
        item {
            search(search: $search) {
                rows {
                    id
                    sku
                    description
                }
                next_cursor
                has_next_page
            }
        }
    }
}
{
    "search": {
        "limit": 50,
        "filter": [
            {
                "expression": {
                    "left": { "column": "sku" },
                    "op": "like",
                    "right": { "literal": { "value": "WIDGET-%" } }
                }
            }
        ]
    }
}