Catalog Product — Create
Equivalent to POST /api/admin/catalog/products.
Step-1 create — mirrors the Bagisto admin Create-Product wizard step 1. Only the bare-minimum fields are accepted at this step; everything else (name, description, price, variants, booking slots, etc.) is added through the Update mutation.
Operation
| Operation | Type |
|---|---|
createAdminCatalogProduct | Mutation |
Input
| Field | Type | Required | Notes |
|---|---|---|---|
sku | String | Yes | Must be unique, and slug-shaped. |
attributeFamilyId | Int | Yes | An existing attribute family id. |
type | String | Yes | One of simple, virtual, downloadable, grouped, bundle, configurable, booking. |
superAttributes | Iterable | Conditional | Required when type is configurable — a map of attribute code (or id) to a non-empty list of option ids, { "color": [1, 2], "size": [6, 7] }. |
clientMutationId | String | No | Echoed back untouched, for correlating a response with its request. |
Every field is declared nullable in the schema, including sku and type. Requiredness is enforced by the API, not by GraphQL validation, so omitting sku is not a schema error — it comes back as a The sku field is required. entry in errors[].
For every type except configurable, the input is just sku, attributeFamilyId, and type. Configurable additionally requires superAttributes, from which the store generates the cartesian product of variants in the same call.
Reading the Payload
The payload is the product itself, so id is its real IRI (/api/admin/catalog/products/<id>), _id its numeric id, and connections resolve against this product — a product created with no images returns images: { edges: [] }.
A freshly created product has almost nothing on it, so most fields come back null. Configurable is the exception: its variants are generated during the create, so variants { edges { node { _id sku } } } is populated straight away.
Errors
Failures come back as HTTP 200 with the message in errors[] and null data:
| Message | Cause |
|---|---|
The sku field is required. | sku omitted |
The sku has already been taken. | Duplicate SKU |
Product type "…" is not supported by this API. Allowed types: simple, virtual, downloadable, grouped, bundle, configurable, booking. | Unrecognised type |
The super_attributes field is required when type=configurable. … | Configurable without options |
You do not have permission to manage products. | Token lacks catalog.products.create |
Validation stops at the first failure, so an input with two problems reports only one.
After Creating
The product exists but is unusable — no name, no price, status: null — so it will not appear on the storefront. Follow with Update, which also carries the per-type structure payloads: variants, bundle options, grouped links, downloadable links and samples, and the booking sub-type (default, appointment, event, rental, or table) with its slots or tickets.

